AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Unitm_reflectionTarget
 
ObjectGuid m_reflectionTargetGuid
 
Position m_reflectionTargetPosition
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
571 :
572 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
573 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
575{
577 m_skipCheck = skipCheck;
578 m_selfContainer = nullptr;
580 m_executedCurrently = false;
583 m_comboTarget = nullptr;
584 m_delayStart = 0;
586
588 m_auraScaleMask = 0;
589 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
590
591 // Get data for type of attack
592 switch (m_spellInfo->DmgClass)
593 {
597 else
599 break;
602 break;
603 default:
604 // Wands
607 else
609 break;
610 }
611
612 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
613
615 // wand case
618 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
619
620 if (originalCasterGUID)
621 m_originalCasterGUID = originalCasterGUID;
622 else
624
627 else
628 {
631 m_originalCaster = nullptr;
632 }
633
635 _triggeredCastFlags = triggerFlags;
636 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
638
639 m_CastItem = nullptr;
640
641 unitTarget = nullptr;
642 itemTarget = nullptr;
643 gameObjTarget = nullptr;
644 destTarget = nullptr;
645 damage = 0;
646 m_reflectionTarget = nullptr;
651 m_damage = 0;
652 m_healing = 0;
653 m_procAttacker = 0;
654 m_procVictim = 0;
655 m_procEx = 0;
656 focusObject = nullptr;
657 m_cast_count = 0;
658 m_glyphIndex = 0;
659 m_preCastSpell = 0;
660 m_spellAura = nullptr;
661 _scriptsLoaded = false;
662
663 //Auto Shot & Shoot (wand)
665
666 m_runesState = 0;
667 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
668 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
669 m_timer = 0; // will set to castime in prepare
670 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
671 m_immediateHandled = false;
672
674
676
677 // Determine if spell can be reflected back to the caster
678 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
682
684 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
685
686 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
688
689 // xinef:
690 _spellTargetsSelected = false;
691
692 m_weaponItem = nullptr;
693}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1638
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3508
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:827
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:472
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:437
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:528
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1559
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1557
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1558
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1154
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:397
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:422
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:548
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:633
SpellSchoolMask
Definition SharedDefines.h:306
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:139
#define sSpellMgr
Definition SpellMgr.h:825
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:244
@ SPELL_FLAG_NORMAL
Definition Spell.h:84
@ SPELL_STATE_NULL
Definition Spell.h:234
@ OFF_ATTACK
Definition Unit.h:212
@ BASE_ATTACK
Definition Unit.h:211
@ RANGED_ATTACK
Definition Unit.h:213
@ DIMINISHING_LEVEL_1
Definition Unit.h:265
Definition ByteBuffer.h:70
Definition Item.h:220
void Clear()
Definition ObjectGuid.h:138
bool IsPlayer() const
Definition Object.h:201
Player * ToPlayer()
Definition Object.h:202
bool IsInWorld() const
Definition Object.h:108
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:489
bool IsPassive() const
Definition SpellInfo.cpp:1098
bool NeedsComboPoints() const
Definition SpellInfo.cpp:1266
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition SpellInfo.cpp:876
bool IsPositive() const
Definition SpellInfo.cpp:1237
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1283
uint32 DmgClass
Definition SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition SpellInfo.cpp:1276
Unit * m_comboTarget
Definition Spell.h:553
int8 m_comboPointGain
Definition Spell.h:554
GameObject * gameObjTarget
Definition Spell.h:665
bool m_referencedFromCurrentSpell
Definition Spell.h:656
bool m_canReflect
Definition Spell.h:632
uint32 m_procVictim
Definition Spell.h:690
Unit * m_originalCaster
Definition Spell.h:620
bool m_needComboPoints
Definition Spell.h:658
uint64 m_delayStart
Definition Spell.h:650
bool _scriptsLoaded
Definition Spell.h:741
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:782
int32 damage
Definition Spell.h:667
SpellEffectHandleMode effectHandleMode
Definition Spell.h:668
int32 m_channeledDuration
Definition Spell.h:631
Aura * m_spellAura
Definition Spell.h:673
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:716
Unit *const m_caster
Definition Spell.h:614
uint8 m_delayAtDamageCount
Definition Spell.h:639
WeaponAttackType m_attackType
Definition Spell.h:628
bool m_immediateHandled
Definition Spell.h:653
uint32 m_spellState
Definition Spell.h:778
ObjectGuid m_originalCasterGUID
Definition Spell.h:618
void CleanupTargetList()
Definition Spell.cpp:2284
int32 m_timer
Definition Spell.h:779
int32 m_casttime
Definition Spell.h:630
Item * itemTarget
Definition Spell.h:664
uint8 m_cast_count
Definition Spell.h:535
int32 m_damage
Definition Spell.h:683
bool m_executedCurrently
Definition Spell.h:657
DiminishingLevels m_diminishLevel
Definition Spell.h:676
float m_damageMultipliers[3]
Definition Spell.h:660
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:796
uint8 m_auraScaleMask
Definition Spell.h:790
SpellCustomErrors m_customError
Definition Spell.h:539
uint8 m_spellFlags
Definition Spell.h:634
bool m_skipCheck
Definition Spell.h:789
int32 m_healing
Definition Spell.h:684
uint32 m_glyphIndex
Definition Spell.h:536
uint8 m_channelTargetEffectMask
Definition Spell.h:698
Item * m_weaponItem
Definition Spell.h:533
Unit * unitTarget
Definition Spell.h:663
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:627
Unit * m_reflectionTarget
Definition Spell.h:669
SpellEvent * _spellEvent
Definition Spell.h:781
bool _spellTargetsSelected
Definition Spell.h:794
ObjectGuid m_reflectionTargetGuid
Definition Spell.h:670
uint32 m_preCastSpell
Definition Spell.h:537
WorldLocation * destTarget
Definition Spell.h:666
Spell ** m_selfContainer
Definition Spell.h:622
uint8 m_applyMultiplierMask
Definition Spell.h:659
DiminishingGroup m_diminishGroup
Definition Spell.h:677
uint32 m_procEx
Definition Spell.h:691
Item * m_CastItem
Definition Spell.h:532
SpellValue *const m_spellValue
Definition Spell.h:616
int32 m_powerCost
Definition Spell.h:629
uint32 m_procAttacker
Definition Spell.h:689
GameObject * focusObject
Definition Spell.h:680
SpellInfo const *const m_spellInfo
Definition Spell.h:531
uint8 m_runesState
Definition Spell.h:637
bool m_autoRepeat
Definition Spell.h:636
Unit * GetCharmerOrOwner() const
Definition Unit.h:1253
uint32 getClassMask() const
Definition Unit.h:828
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:199
Definition Spell.h:104
Definition Spell.h:221

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), ObjectGuid::Clear(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_reflectionTarget, m_reflectionTargetGuid, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

Spell::~Spell ( )
696{
697 // unload scripts
698 while (!m_loadedScripts.empty())
699 {
700 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
701 (*itr)->_Unload();
702 delete (*itr);
703 m_loadedScripts.erase(itr);
704 }
705
707 {
708 // Clean the reference to avoid later crash.
709 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
710 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
711 *m_selfContainer = nullptr;
712 }
713
714 delete m_spellValue;
715
717}
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
uint32 Id
Definition SpellInfo.h:320
void CheckEffectExecuteData()
Definition Spell.cpp:8480
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:756

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3748{
3749 // update pointers base at GUIDs to prevent access to non-existed already object
3750 if (!UpdatePointers())
3751 {
3752 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3753 cancel();
3754 return;
3755 }
3756
3757 // cancel at lost explicit target during cast
3759 {
3760 cancel();
3761 return;
3762 }
3763
3764 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3766 {
3768 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3770
3771 if (Unit* charm = m_caster->GetCharm())
3772 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3773 }
3774
3775 if (Player* playerCaster = m_caster->ToPlayer())
3776 {
3777 // now that we've done the basic check, now run the scripts
3778 // should be done before the spell is actually executed
3779 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3780
3781 // As of 3.0.2 pets begin attacking their owner's target immediately
3782 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3783 // This prevents spells such as Hunter's Mark from triggering pet attack
3784 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3786 if (!playerCaster->m_Controlled.empty())
3787 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3788 if (Unit* pet = *itr)
3789 if (pet->IsAlive() && pet->IsCreature())
3790 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3791 }
3792
3794
3798
3800
3801 Player* modOwner = m_caster->GetSpellModOwner();
3802 // skip check if done already (for instant cast spells for example)
3803 if (!skipCheck)
3804 {
3805 SpellCastResult castResult = CheckCast(false);
3806 if (castResult != SPELL_CAST_OK)
3807 {
3808 SendCastResult(castResult);
3809 SendInterrupted(0);
3810
3811 finish(false);
3812 SetExecutedCurrently(false);
3813 return;
3814 }
3815
3816 // additional check after cast bar completes (must not be in CheckCast)
3817 // if trade not complete then remember it in trade data
3819 {
3820 if (m_caster->IsPlayer())
3821 {
3822 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3823 {
3824 if (!my_trade->IsInAcceptProcess())
3825 {
3826 // Spell will be casted at completing the trade. Silently ignore at this place
3827 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3829 SendInterrupted(0);
3830
3831 finish(false);
3832 SetExecutedCurrently(false);
3833 return;
3834 }
3835 }
3836 }
3837 }
3838 }
3839
3840 if (modOwner)
3841 modOwner->SetSpellModTakingSpell(this, true);
3842
3845
3846 if (modOwner)
3847 modOwner->SetSpellModTakingSpell(this, false);
3848
3849 // Spell may be finished after target map check
3851 {
3852 SendInterrupted(0);
3853 finish(false);
3854 SetExecutedCurrently(false);
3855 return;
3856 }
3857
3858 if (modOwner)
3859 modOwner->SetSpellModTakingSpell(this, true);
3860
3862
3864
3865 if (modOwner)
3866 modOwner->SetSpellModTakingSpell(this, false);
3867
3868 // traded items have trade slot instead of guid in m_itemTargetGUID
3869 // set to real guid to be sent later to the client
3871
3872 if (m_caster->IsPlayer())
3873 {
3875 {
3878 }
3879
3881 }
3882
3884 {
3885 // Powers have to be taken before SendSpellGo
3886 TakePower();
3887 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3888 }
3889 else if (Item* targetItem = m_targets.GetItemTarget())
3890 {
3892 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3893 TakeReagents();
3894 }
3895
3897
3898 // CAST SPELL
3899 if (modOwner)
3900 modOwner->SetSpellModTakingSpell(this, true);
3901
3903
3905
3906 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3907 SendSpellGo();
3908
3909 if (modOwner)
3910 modOwner->SetSpellModTakingSpell(this, false);
3911
3912 if (m_originalCaster)
3913 {
3914 // Handle procs on cast
3915 uint32 procAttacker = m_procAttacker;
3916 if (!procAttacker)
3917 {
3918 bool IsPositive = m_spellInfo->IsPositive();
3920 {
3922 }
3923 else
3924 {
3926 }
3927 }
3928
3929 uint32 procEx = PROC_EX_NORMAL_HIT;
3930
3931 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3932 {
3933 if (ihit->missCondition != SPELL_MISS_NONE)
3934 {
3935 continue;
3936 }
3937
3938 if (!ihit->crit)
3939 {
3940 continue;
3941 }
3942
3943 procEx |= PROC_EX_CRITICAL_HIT;
3944 break;
3945 }
3946
3949 }
3950
3951 if (modOwner)
3952 modOwner->SetSpellModTakingSpell(this, true);
3953
3955 if (resetAttackTimers)
3956 {
3958 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3959 {
3960 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3961 {
3962 resetAttackTimers = false;
3963 break;
3964 }
3965 }
3966 }
3967
3968 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
3969 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
3970 {
3971 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
3972 // in case delayed spell remove item at cast delay start
3973 TakeCastItem();
3974
3975 // Okay, maps created, now prepare flags
3976 m_immediateHandled = false;
3978 SetDelayStart(0);
3979
3982
3983 // remove all applied mods at this point
3984 // dont allow user to use them twice in case spell did not reach current target
3985 if (modOwner)
3986 modOwner->RemoveSpellMods(this);
3987
3988 // Xinef: why do we keep focus after spell is sent to air?
3989 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
3990 // Xinef: we get focused to it out of nowhere...
3991 if (Creature* creatureCaster = m_caster->ToCreature())
3992 creatureCaster->ReleaseFocus(this);
3993 }
3994 else
3995 {
3996 // Immediate spell, no big deal
3998 }
3999
4000 if (resetAttackTimers)
4001 {
4002 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4003 {
4004 resetAttackTimers = false;
4005 }
4006
4007 if (resetAttackTimers)
4008 {
4010
4012 {
4014 }
4015
4017 }
4018 }
4019
4021
4022 if (modOwner)
4023 modOwner->SetSpellModTakingSpell(this, false);
4024
4025 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4026 {
4027 for (int32 id : *spell_triggered)
4028 {
4029 if (id < 0)
4031 else
4033 }
4034 }
4035
4036 // Interrupt Spell casting
4037 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4039 if (Unit* target = m_targets.GetUnitTarget())
4040 if (target->IsCreature())
4041 m_caster->CastSpell(target, 32747, true);
4042
4043 // xinef: start combat at cast for delayed spells, only for explicit target
4044 if (Unit* target = m_targets.GetUnitTarget())
4047 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4048
4049 if (m_caster->IsPlayer())
4052
4053 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4054
4055 SetExecutedCurrently(false);
4056
4057 // Call CreatureAI hook OnSpellCastFinished
4058 if (m_originalCaster)
4059 if (Creature* caster = m_originalCaster->ToCreature())
4060 if (caster->IsAIEnabled)
4061 caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST);
4062}
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:143
std::int32_t int32
Definition Define.h:103
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ CHEAT_COOLDOWN
Definition Player.h:996
#define sScriptMgr
Definition ScriptMgr.h:723
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:663
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:845
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:484
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:430
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:521
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1556
@ SPELL_MISS_NONE
Definition SharedDefines.h:1530
SpellCastResult
Definition SharedDefines.h:959
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:987
@ SPELL_CAST_OK
Definition SharedDefines.h:1149
@ SPELL_AURA_MOD_CHARM
Definition SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:143
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:47
@ PROC_EX_CRITICAL_HIT
Definition SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:125
@ PROC_FLAG_NONE
Definition SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:131
@ SPELL_FINISHED_SUCCESSFUL_CAST
Definition Spell.h:98
@ SPELL_STATE_DELAYED
Definition Spell.h:239
@ SPELL_STATE_FINISHED
Definition Spell.h:237
@ UNIT_STATE_CASTING
Definition UnitDefines.h:185
Definition Creature.h:47
uint32 GetEntry() const
Definition Object.h:116
bool IsCreature() const
Definition Object.h:205
Creature * ToCreature()
Definition Object.h:206
Definition Pet.h:41
Definition Player.h:1071
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2163
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10069
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:13923
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:9991
Pet * GetPet() const
Definition Player.cpp:8955
bool GetCommandStatus(uint32 command) const
Definition Player.h:1184
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9105
TradeData * GetTradeData() const
Definition Player.h:1375
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3537
WorldObject * GetObjectTarget() const
Definition Spell.cpp:311
void UpdateTradeSlotItem()
Definition Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:316
Item * GetItemTarget() const
Definition Spell.h:149
uint32 GetTargetMask() const
Definition Spell.h:127
Unit * GetUnitTarget() const
Definition Spell.cpp:232
float Speed
Definition SpellInfo.h:370
bool IsChanneled() const
Definition SpellInfo.cpp:1256
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2364
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:893
SpellInfo const * GetSpellInfo() const
Definition Spell.h:587
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8534
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8740
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:565
SpellCastTargets m_targets
Definition Spell.h:538
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:787
void handle_immediate()
Definition Spell.cpp:4064
void SendSpellGo()
Definition Spell.cpp:4756
void TakeReagents()
Definition Spell.cpp:5491
void SetExecutedCurrently(bool yes)
Definition Spell.h:573
void SendInterrupted(uint8 result)
Definition Spell.cpp:5133
void PrepareScriptHitHandlers()
Definition Spell.cpp:8566
void CallScriptOnCastHandlers()
Definition Spell.cpp:8521
void cancel(bool bySelf=false)
Definition Spell.cpp:3657
void SendSpellCooldown()
Definition Spell.cpp:4304
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8508
void HandleLaunchPhase()
Definition Spell.cpp:8211
bool UpdatePointers()
Definition Spell.cpp:7841
void SetDelayStart(uint64 m_time)
Definition Spell.h:575
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:697
void SelectSpellTargets()
Definition Spell.cpp:821
void TakePower()
Definition Spell.cpp:5274
SpellCastResult CheckCast(bool strict)
Definition Spell.cpp:5613
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4628
uint64 GetDelayMoment() const
Definition Spell.h:576
void TakeCastItem()
Definition Spell.cpp:5211
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8055
void finish(bool ok=true)
Definition Spell.cpp:4436
Definition TradeData.h:36
Definition Unit.h:650
bool HasOffhandWeaponForAttack() const
Definition Unit.h:968
void ClearUnitState(uint32 f)
Definition Unit.h:722
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1391
Unit * GetCharm() const
Definition Unit.cpp:10748
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:666
Player * GetSpellModOwner() const
Definition Unit.cpp:16589
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition Unit.cpp:13788
bool IsPet() const
Definition Unit.h:780
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4159
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1194
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4978
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition Unit.cpp:6478
bool HasUnitState(const uint32 f) const
Definition Unit.h:721
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:10293
bool IsControlledByPlayer() const
Definition Unit.h:1274
void SetInFront(WorldObject const *target)
Definition Unit.cpp:20273
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:643
int8 effectIndex
Definition Spell.h:290
SpellInfo const * spellInfo
Definition Spell.h:289

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_FINISHED_SUCCESSFUL_CAST, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4230{
4231 // Take for real after all targets are processed
4233 {
4235 }
4236
4237 // Real add combo points from effects
4239 {
4240 // remove Premed-like effects unless they were caused by ourselves
4241 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4243 {
4245 }
4246
4248 }
4249
4251 {
4253 }
4254
4257 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4258 {
4259 // Xinef: Properly clear infinite cooldowns in some cases
4260 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4263 }
4264
4265 // Handle procs on finish
4266 if (m_originalCaster)
4267 {
4268 uint32 procAttacker = m_procAttacker;
4269 if (!procAttacker)
4270 {
4271 bool IsPositive = m_spellInfo->IsPositive();
4273 {
4275 }
4276 else
4277 {
4279 }
4280 }
4281
4282 uint32 procEx = PROC_EX_NORMAL_HIT;
4283 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4284 {
4285 if (ihit->missCondition != SPELL_MISS_NONE)
4286 {
4287 continue;
4288 }
4289
4290 if (!ihit->crit)
4291 {
4292 continue;
4293 }
4294
4295 procEx |= PROC_EX_CRITICAL_HIT;
4296 break;
4297 }
4298
4301 }
4302}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition SharedDefines.h:808
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition SpellMgr.h:245
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition Player.cpp:11089
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1212
bool IsAutoRepeat() const
Definition Spell.h:559
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8045
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:987
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:10693
void ClearComboPoints()
Definition Unit.cpp:16891
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:16865
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5179

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4202{
4203 m_spellAura = nullptr;
4204 // initialize Diminishing Returns Data
4207
4208 // handle some immediate features of the spell here
4210
4212
4213 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4214 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4215 {
4216 // don't do anything for empty effect
4217 if (!m_spellInfo->Effects[j].IsEffect())
4218 continue;
4219
4220 // call effect handlers to handle destination hit
4221 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4222 }
4223
4224 // process items
4225 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4226 DoAllEffectOnTarget(&(*ihit));
4227}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:246
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
void HandleThreatSpells()
Definition Spell.cpp:5540
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5587
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:714
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2522

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
542 {
543 if (target != m_comboTarget)
544 {
545 m_comboTarget = target;
546 m_comboPointGain = amount;
547 }
548 else
549 {
550 m_comboPointGain += amount;
551 }
552 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2518{
2519 m_destTargets[effIndex] = dest;
2520}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2427{
2428 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2429 {
2430 if (!m_spellInfo->Effects[effIndex].IsEffect())
2431 effectMask &= ~(1 << effIndex);
2432 else
2433 {
2434 switch (m_spellInfo->Effects[effIndex].Effect)
2435 {
2439 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2440 effectMask &= ~(1 << effIndex);
2441 break;
2442 default:
2443 break;
2444 }
2445 }
2446 }
2447
2448 if (!effectMask)
2449 return;
2450
2451 ObjectGuid targetGUID = go->GetGUID();
2452
2453 // Lookup target in already in list
2454 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2455 {
2456 if (targetGUID == ihit->targetGUID) // Found in list
2457 {
2458 ihit->effectMask |= effectMask; // Add only effect mask
2459 return;
2460 }
2461 }
2462
2463 // This is new target calculate data for him
2464
2465 GOTargetInfo target;
2466 target.targetGUID = targetGUID;
2467 target.effectMask = effectMask;
2468 target.processed = false; // Effects not apply on target
2469
2470 // Spell have speed - need calculate incoming time
2471 if (m_spellInfo->Speed > 0.0f)
2472 {
2473 // calculate spell incoming interval
2474 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2475 if (dist < 5.0f)
2476 dist = 5.0f;
2477 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2478 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2479 m_delayMoment = target.timeDelay;
2480 }
2481 else
2482 target.timeDelay = 0LL;
2483
2484 // Add target to list
2485 m_UniqueGOTargetInfo.push_back(target);
2486}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1604
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:877
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:878
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:876
Definition ObjectGuid.h:118
uint64 m_delayMoment
Definition Spell.h:651
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:707
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1278

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2489{
2490 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2491 if (!m_spellInfo->Effects[effIndex].IsEffect())
2492 effectMask &= ~(1 << effIndex);
2493
2494 // no effects left
2495 if (!effectMask)
2496 return;
2497
2498 // Lookup target in already in list
2499 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2500 {
2501 if (item == ihit->item) // Found in list
2502 {
2503 ihit->effectMask |= effectMask; // Add only effect mask
2504 return;
2505 }
2506 }
2507
2508 // This is new target add data
2509
2510 ItemTargetInfo target;
2511 target.item = item;
2512 target.effectMask = effectMask;
2513
2514 m_UniqueItemInfo.push_back(target);
2515}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2294{
2295 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2296 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2297 effectMask &= ~(1 << effIndex);
2298
2299 // no effects left
2300 if (!effectMask)
2301 return;
2302
2303 if (checkIfValid)
2304 {
2305 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2306 if (res != SPELL_CAST_OK)
2307 return;
2308 }
2309
2310 // Check for effect immune skip if immuned
2311 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2312 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2313 effectMask &= ~(1 << effIndex);
2314
2315 ObjectGuid targetGUID = target->GetGUID();
2316
2317 // Lookup target in already in list
2318 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2319 {
2320 if (targetGUID == ihit->targetGUID) // Found in list
2321 {
2322 ihit->effectMask |= effectMask; // Immune effects removed from mask
2323 ihit->scaleAura = false;
2324 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2325 {
2326 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2327 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2328 ihit->scaleAura = true;
2329 }
2330
2331 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2332 return;
2333 }
2334 }
2335
2336 // This is new target calculate data for him
2337
2338 // Get spell hit result on target
2339 TargetInfo targetInfo;
2340 targetInfo.targetGUID = targetGUID; // Store target GUID
2341 targetInfo.effectMask = effectMask; // Store all effects not immune
2342 targetInfo.processed = false; // Effects not apply on target
2343 targetInfo.alive = target->IsAlive();
2344 targetInfo.damage = 0;
2345 targetInfo.crit = false;
2346 targetInfo.scaleAura = false;
2347 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2348 {
2349 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2350 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2351 targetInfo.scaleAura = true;
2352 }
2353
2354 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2355
2356 // Calculate hit result
2357 if (m_originalCaster)
2358 {
2359 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2360 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2361 {
2362 targetInfo.missCondition = SPELL_MISS_NONE;
2363 }
2364 }
2365 else
2366 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2367
2368 // Spell have speed - need calculate incoming time
2369 // Incoming time is zero for self casts. At least I think so.
2370 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2371 {
2372 // calculate spell incoming interval
2374 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2375
2376 if (dist < 5.0f)
2377 dist = 5.0f;
2378 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2379
2380 // Calculate minimum incoming time
2381 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2382 m_delayMoment = targetInfo.timeDelay;
2383 }
2384 else
2385 targetInfo.timeDelay = 0LL;
2386
2387 // If target reflect spell back to caster
2388 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2389 {
2390 // Calculate reflected spell result on caster
2392
2393 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2394 targetInfo.reflectResult = SPELL_MISS_PARRY;
2395
2396 // Increase time interval for reflected spells by 1.5
2398 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2399
2401
2402 // HACK: workaround check for succubus seduction case
2404 if (m_caster->IsPet())
2405 {
2406 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2407 switch (ci->family)
2408 {
2410 {
2411 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2412 cancel();
2413 }
2414 break;
2415 return;
2416 }
2417 }
2418 }
2419 else
2420 targetInfo.reflectResult = SPELL_MISS_NONE;
2421
2422 // Add target to list
2423 m_UniqueTargetInfo.push_back(targetInfo);
2424}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1650
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2675
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1534
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1537
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1536
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1541
@ SPELL_FLAG_REFLECTED
Definition Spell.h:85
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Spell.h:853
Definition SpellInfo.h:316
uint32 SpellLevel
Definition SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2513
uint32 SpellIconID
Definition SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1759
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:7903
bool IsAlive() const
Definition Unit.h:1748
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3508
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:13086
uint8 GetLevel() const
Definition Unit.h:1065
EventProcessor m_Events
Definition Object.h:731
Definition CreatureData.h:186
uint32 family
Definition CreatureData.h:217
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122
Definition Spell.h:265
bool processed
Definition Spell.h:271
int32 damage
Definition Spell.h:275
SpellMissInfo missCondition
Definition Spell.h:268
bool scaleAura
Definition Spell.h:274
bool crit
Definition Spell.h:273
uint64 timeDelay
Definition Spell.h:267
ObjectGuid targetGUID
Definition Spell.h:266
SpellMissInfo reflectResult
Definition Spell.h:269
bool alive
Definition Spell.h:272
uint8 effectMask
Definition Spell.h:270

References EventProcessor::AddEventAtOffset(), TargetInfo::alive, cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, WorldObject::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
902{
903 if (m_targets.HasDst())
904 {
905 if (m_targets.HasTraj())
906 {
907 float speed = m_targets.GetSpeedXY();
908 if (speed > 0.0f)
909 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
910 }
911 else if (m_spellInfo->Speed > 0.0f)
912 {
913 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
914 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
915 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
916 }
917 }
918
919 return 0;
920}
bool HasTraj() const
Definition Spell.h:176
bool HasDst() const
Definition Spell.h:175
float GetSpeedXY() const
Definition Spell.h:184
float GetDist2d() const
Definition Spell.h:183
WorldLocation const * GetDstPos() const
Definition Spell.cpp:401
float GetExactDist(float x, float y, float z) const
Definition Position.h:182

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
@ MOVE_RUN
Definition UnitDefines.h:354
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:76
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:89
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:14513
double gravity
Definition MovementUtil.cpp:24

References baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), Movement::gravity, Unit::IsControlledByPlayer(), m_caster, m_spellInfo, MOVE_RUN, playerBaseMoveSpeed, and Object::ToCreature().

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition Unit.cpp:14881
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:223

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8535{
8536 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8537 {
8538 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8539 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8540 for (; hookItr != hookItrEnd; ++hookItr)
8541 (*hookItr).Call(*scritr);
8542
8543 (*scritr)->_FinishScriptCall();
8544 }
8545}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8647{
8648 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8649 {
8650 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8651 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8652 for (; hookItr != hookItrEnd; ++hookItr)
8653 (*hookItr).Call(*scritr);
8654
8655 (*scritr)->_FinishScriptCall();
8656 }
8657}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8509{
8510 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8511 {
8512 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8513 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8514 for (; hookItr != hookItrEnd; ++hookItr)
8515 (*hookItr).Call(*scritr);
8516
8517 (*scritr)->_FinishScriptCall();
8518 }
8519}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8621{
8622 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8623 {
8624 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8625 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8626 for (; hookItr != hookItrEnd; ++hookItr)
8627 (*hookItr).Call(*scritr, missInfo);
8628
8629 (*scritr)->_FinishScriptCall();
8630 }
8631}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8548{
8550 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8551 {
8552 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8553 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8554 for (; hookItr != hookItrEnd; ++hookItr)
8555 {
8556 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8557 if (retVal == SPELL_CAST_OK)
8558 retVal = tempResult;
8559 }
8560
8561 (*scritr)->_FinishScriptCall();
8562 }
8563 return retVal;
8564}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8688{
8689 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8690 {
8691 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8692 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8693 for (; hookItr != hookItrEnd; ++hookItr)
8694 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8695 hookItr->Call(*scritr, target);
8696
8697 (*scritr)->_FinishScriptCall();
8698 }
8699}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8573{
8574 // execute script effect handler hooks and check if effects was prevented
8575 bool preventDefault = false;
8576 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8577 {
8578 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8579 SpellScriptHookType hookType;
8580 switch (mode)
8581 {
8583 effItr = (*scritr)->OnEffectLaunch.begin();
8584 effEndItr = (*scritr)->OnEffectLaunch.end();
8586 break;
8588 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8589 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8591 break;
8593 effItr = (*scritr)->OnEffectHit.begin();
8594 effEndItr = (*scritr)->OnEffectHit.end();
8596 break;
8598 effItr = (*scritr)->OnEffectHitTarget.begin();
8599 effEndItr = (*scritr)->OnEffectHitTarget.end();
8601 break;
8602 default:
8603 ABORT();
8604 return false;
8605 }
8606 (*scritr)->_PrepareScriptCall(hookType);
8607 for (; effItr != effEndItr; ++effItr)
8608 // effect execution can be prevented
8609 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8610 (*effItr).Call(*scritr, effIndex);
8611
8612 if (!preventDefault)
8613 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8614
8615 (*scritr)->_FinishScriptCall();
8616 }
8617 return preventDefault;
8618}
#define ABORT
Definition Errors.h:76
SpellScriptHookType
Definition SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition SpellScript.h:162
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:245
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:247

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8660{
8661 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8662 {
8663 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8664 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8665 for (; hookItr != hookItrEnd; ++hookItr)
8666 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8667 hookItr->Call(*scritr, targets);
8668
8669 (*scritr)->_FinishScriptCall();
8670 }
8671}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8674{
8675 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8676 {
8677 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8678 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8679 for (; hookItr != hookItrEnd; ++hookItr)
8680 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8681 hookItr->Call(*scritr, target);
8682
8683 (*scritr)->_FinishScriptCall();
8684 }
8685}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8522{
8523 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8524 {
8525 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8526 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8527 for (; hookItr != hookItrEnd; ++hookItr)
8528 (*hookItr).Call(*scritr);
8529
8530 (*scritr)->_FinishScriptCall();
8531 }
8532}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8634{
8635 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8636 {
8637 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8638 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8639 for (; hookItr != hookItrEnd; ++hookItr)
8640 (*hookItr).Call(*scritr);
8641
8642 (*scritr)->_FinishScriptCall();
8643 }
8644}
@ SPELL_SCRIPT_HOOK_HIT
Definition SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6973{
6974 ObjectGuid targetguid = target->GetGUID();
6975
6976 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6977 {
6979 {
6980 if (m_spellInfo->StackAmount <= 1)
6981 {
6982 if (target->HasAuraEffect(m_spellInfo->Id, j))
6983 return false;
6984 }
6985 else
6986 {
6987 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
6988 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
6989 return false;
6990 }
6991 }
6992 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
6993 {
6994 if (target->HasAuraEffect(m_spellInfo->Id, j))
6995 return false;
6996 }
6997 }
6998
6999 SpellCastResult result = CheckPetCast(target);
7000
7001 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7002 {
7004 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7005 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7006 if (ihit->targetGUID == targetguid)
7007 return true;
7008 }
7009 return false; //target invalid
7010}
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:795
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition SharedDefines.h:1094
Definition SpellAuraEffects.h:39
uint32 StackAmount
Definition SpellInfo.h:371
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:6779
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:5563
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition Unit.cpp:5737

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3658{
3660 return;
3661
3662 uint32 oldState = m_spellState;
3664
3665 m_autoRepeat = false;
3666 switch (oldState)
3667 {
3671
3672 if (m_caster->IsPlayer())
3673 {
3675 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3676 }
3677 [[fallthrough]];
3680 break;
3682 if (!bySelf)
3683 {
3684 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3685 if ((*ihit).missCondition == SPELL_MISS_NONE)
3686 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3687 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3688
3691
3694 }
3695
3697 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3698
3699 // spell is canceled-take mods and clear list
3700 if (Player* player = m_caster->GetSpellModOwner())
3701 player->RemoveSpellMods(this);
3702
3703 m_appliedMods.clear();
3704 break;
3705 default:
3706 break;
3707 }
3708
3710 if (m_selfContainer && *m_selfContainer == this)
3711 *m_selfContainer = nullptr;
3712
3713 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3715 {
3717 }
3718
3719 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3721
3722 //set state back so finish will be processed
3723 m_spellState = oldState;
3724
3725 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3726
3727 finish(false);
3728}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition SharedDefines.h:861
@ SPELL_FAILED_INTERRUPTED
Definition SharedDefines.h:1000
@ AURA_REMOVE_BY_CANCEL
Definition SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition Spell.h:235
@ SPELL_STATE_CASTING
Definition Spell.h:236
bool NeedSendSpectatorData() const
Definition Player.cpp:15468
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5150
void CancelGlobalCooldown()
Definition Spell.cpp:8875
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:571
UsedSpellMods m_appliedMods
Definition Spell.h:556
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6297
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6241
Map * FindMap() const
Definition Object.h:622
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition ArenaSpectator.h:80

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, sScriptMgr, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8876{
8878 return;
8879
8880 // Cancel global cooldown when interrupting current cast
8882 return;
8883
8884 // Only players or controlled units have global cooldown
8885 if (m_caster->GetCharmInfo())
8887 else if (m_caster->IsPlayer())
8889}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:540
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1800
uint32 StartRecoveryTime
Definition SpellInfo.h:351
CharmInfo * GetCharmInfo()
Definition Unit.h:1248
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1535
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition CharmInfo.h:160

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8725{
8726 // Relentless strikes, proc only from first effect
8727 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8728 return effMask & (1 << EFFECT_0);
8729
8730 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8731 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8732 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8733 {
8734 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8735 return true;
8736 }
8737 return effMask;
8738}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1421
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:542

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8340{
8341 if (!lockId) // possible case for GO and maybe for items.
8342 return SPELL_CAST_OK;
8343
8344 // Get LockInfo
8345 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8346
8347 if (!lockInfo)
8349
8350 bool reqKey = false; // some locks not have reqs
8351
8352 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8353 {
8354 switch (lockInfo->Type[j])
8355 {
8356 // check key item (many fit cases can be)
8357 case LOCK_KEY_ITEM:
8358 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8359 return SPELL_CAST_OK;
8360 reqKey = true;
8361 break;
8362 // check key skill (only single first fit case can be)
8363 case LOCK_KEY_SKILL:
8364 {
8365 reqKey = true;
8366
8367 // wrong locktype, skip
8368 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8369 continue;
8370
8371 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8372
8373 if (skillId != SKILL_NONE)
8374 {
8375 reqSkillValue = lockInfo->Skill[j];
8376
8377 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8378 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8379 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8380
8381 // skill bonus provided by casting spell (mostly item spells)
8382 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8383 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8385 {
8386 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8387 }
8388
8389 if (skillValue < reqSkillValue)
8391 }
8392
8393 return SPELL_CAST_OK;
8394 }
8395 case LOCK_KEY_SPELL:
8396 {
8397 if (m_spellInfo->Id == lockInfo->Index[j])
8398 {
8399 return SPELL_CAST_OK;
8400 }
8401 reqKey = true;
8402 break;
8403 }
8404 }
8405 }
8406
8407 if (reqKey)
8409
8410 return SPELL_CAST_OK;
8411}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1306
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1441
LockType
Definition SharedDefines.h:2602
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2596
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2597
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2598
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:972
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:1009
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3270
@ SKILL_NONE
Definition SharedDefines.h:3114
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3225
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5447
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1005
Definition DBCStructure.h:1309
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1311
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1312
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1313

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3731{
3732 Player* modOwner = m_caster->GetSpellModOwner();
3733 Spell* lastMod = nullptr;
3734 if (modOwner)
3735 {
3736 lastMod = modOwner->m_spellModTakingSpell;
3737 if (lastMod)
3738 modOwner->SetSpellModTakingSpell(lastMod, false);
3739 }
3740
3741 _cast(skipCheck);
3742
3743 if (lastMod)
3744 modOwner->SetSpellModTakingSpell(lastMod, true);
3745}
Spell * m_spellModTakingSpell
Definition Player.h:2556
Definition Spell.h:295
void _cast(bool skipCheck)
Definition Spell.cpp:3747

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5614{
5615 // check death state
5618
5619 // Spectator check
5620 if (m_caster->IsPlayer())
5621 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5622 return SPELL_FAILED_NOT_HERE;
5623
5625
5626 sScriptMgr->OnSpellCheckCast(this, strict, res);
5627
5628 if (res != SPELL_CAST_OK)
5629 return res;
5630
5631 // check cooldowns to prevent cheating
5633 {
5634 if (m_caster->IsPlayer())
5635 {
5636 //can cast triggered (by aura only?) spells while have this flag
5639
5641 {
5644 else
5646 }
5647
5648 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5651 }
5654 }
5655
5657 {
5660 }
5661
5662 // Check global cooldown
5665
5666 // only triggered spells can be processed an ended battleground
5667 if (!IsTriggered() && m_caster->IsPlayer())
5669 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5671
5672 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5673 {
5675 !m_caster->IsOutdoors())
5677
5681 }
5682
5683 // only check at first call, Stealth auras are already removed at second call
5684 // for now, ignore triggered spells
5686 {
5687 bool checkForm = true;
5688 // Ignore form req aura
5690 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5691 {
5692 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5693 continue;
5694 checkForm = false;
5695 break;
5696 }
5697 if (checkForm)
5698 {
5699 // Cannot be used in this stance/form
5701 if (shapeError != SPELL_CAST_OK)
5702 return shapeError;
5703
5706 }
5707 }
5708
5710 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5711 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5713
5714 bool reqCombat = true;
5716 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5717 {
5718 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5719 {
5720 m_needComboPoints = false;
5721 if ((*j)->GetMiscValue() == 1)
5722 {
5723 reqCombat = false;
5724 break;
5725 }
5726 }
5727 }
5728
5729 // caster state requirements
5730 // not for triggered spells (needed by execute)
5732 {
5737
5738 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5743
5744 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5746 }
5747
5748 // Xinef: exploit protection
5750 {
5751 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5752 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5753 if (instanceScript->IsEncounterInProgress())
5754 {
5755 if (Group* group = m_caster->ToPlayer()->GetGroup())
5756 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5757 if (Player* member = itr->GetSource())
5758 if (member->IsInMap(m_caster))
5759 if (Unit* victim = member->GetVictim())
5760 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5761 {
5762 m_caster->CombatStart(victim);
5763 victim->AddThreat(m_caster, 1.0f);
5764 break;
5765 }
5767 }
5768 }
5769
5770 // cancel autorepeat spells if cast start when moving
5771 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5772 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5773 {
5774 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5777 return SPELL_FAILED_MOVING;
5778 }
5779
5780 Vehicle* vehicle = m_caster->GetVehicle();
5782 {
5783 uint16 checkMask = 0;
5784 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5785 {
5786 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5788 {
5789 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5790 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5791 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5792 break;
5793 }
5794 }
5795
5798
5799 if (!checkMask)
5800 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5801
5802 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5803 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5805 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5807 }
5808
5809 // check spell cast conditions from database
5810 {
5813 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5814 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5815 {
5816 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5817 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5818 {
5822 }
5823 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5826 }
5827 }
5828
5829 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5830 // those spells may have incorrect target entries or not filled at all (for example 15332)
5831 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5832 // also, such casts shouldn't be sent to client
5833 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5835 {
5836 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5837 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5839 {
5841 if (castResult != SPELL_CAST_OK)
5842 return castResult;
5843 }
5844 }
5845
5846 if (Unit* target = m_targets.GetUnitTarget())
5847 {
5848 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5849 if (castResult != SPELL_CAST_OK)
5850 return castResult;
5851
5852 if (target != m_caster)
5853 {
5854 // Must be behind the target
5855 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5857
5858 // Target must be facing you
5859 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5861
5864 {
5865 bool castedByGameobject = false;
5866 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5868 {
5869 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5870 }
5871 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5872 {
5873 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5874 {
5875 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5876 }
5877 }
5878
5879 if (castedByGameobject)
5880 {
5881 // If spell casted by gameobject then ignore M2 models
5882 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5883 }
5884
5886 {
5888 }
5889 }
5890 }
5891 }
5892
5893 // Check for line of sight for spells with dest
5894 if (m_targets.HasDst())
5895 {
5896 float x, y, z;
5897 m_targets.GetDstPos()->GetPosition(x, y, z);
5898
5901 {
5902 bool castedByGameobject = false;
5903 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5905 {
5906 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5907 }
5908 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5909 {
5910 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5911 {
5912 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5913 }
5914 }
5915
5916 if (castedByGameobject)
5917 {
5918 // If spell casted by gameobject then ignore M2 models
5919 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5920 }
5921
5923 {
5925 }
5926 }
5927 }
5928
5929 // check pet presence
5930 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5931 {
5932 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5933 {
5935 {
5936 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5938 else
5939 return SPELL_FAILED_NO_PET;
5940 }
5941 break;
5942 }
5943 }
5944 // Spell casted only on battleground
5946 if (!m_caster->ToPlayer()->InBattleground())
5948
5949 // do not allow spells to be cast in arenas
5950 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5951 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5954 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5955 if (mapEntry->IsBattleArena())
5957
5958 // zone check
5960 {
5961 uint32 zone, area;
5962 m_caster->GetZoneAndAreaId(zone, area);
5963
5965 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5966 if (locRes != SPELL_CAST_OK)
5967 return locRes;
5968 }
5969
5970 // not let players cast spells at mount (and let do it to creatures)
5973 {
5974 if (m_caster->IsInFlight())
5976 else
5978 }
5979
5980 SpellCastResult castResult = SPELL_CAST_OK;
5981
5982 // always (except passive spells) check items (focus object can be required for any type casts)
5983 if (!m_spellInfo->IsPassive())
5984 {
5985 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
5986 castResult = CheckSpellFocus();
5987 if (castResult != SPELL_CAST_OK)
5988 return castResult;
5989
5990 castResult = CheckItems();
5991 if (castResult != SPELL_CAST_OK)
5992 return castResult;
5993 }
5994
5995 // Triggered spells also have range check
5997 castResult = CheckRange(strict);
5998 if (castResult != SPELL_CAST_OK)
5999 return castResult;
6000
6002 {
6003 castResult = CheckPower();
6004 if (castResult != SPELL_CAST_OK)
6005 return castResult;
6006 }
6007
6009 {
6010 return SPELL_CAST_OK;
6011 }
6012
6013 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6015 {
6017 if (castResult != SPELL_CAST_OK)
6018 return castResult;
6019
6020 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6022 {
6024 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6025 if (itr->type == m_spellInfo->Mechanic)
6027 }
6028 }
6029
6030 // script hook
6031 castResult = CallScriptCheckCastHandlers();
6032 if (castResult != SPELL_CAST_OK)
6033 return castResult;
6034
6035 bool hasDispellableAura = false;
6036 bool hasNonDispelEffect = false;
6037 uint32 dispelMask = 0;
6038 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6039 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6040 {
6042 {
6043 hasDispellableAura = true;
6044 break;
6045 }
6046
6047 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6048 }
6049 else if (m_spellInfo->Effects[i].IsEffect())
6050 {
6051 hasNonDispelEffect = true;
6052 break;
6053 }
6054
6055 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6056 {
6057 if (Unit* target = m_targets.GetUnitTarget())
6058 {
6059 // Xinef: do not allow to cast on hostile targets in sanctuary
6060 if (!m_caster->IsFriendlyTo(target))
6061 {
6062 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6063 {
6064 // Xinef: fix for duels
6065 Player* player = m_caster->ToPlayer();
6066 if (!player || !player->duel || target != player->duel->Opponent)
6068 }
6069 }
6070
6071 DispelChargesList dispelList;
6072 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6073
6074 if (dispelList.empty())
6076 }
6077 }
6078
6079 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6080 {
6081 // for effects of spells that have only one target
6082 switch (m_spellInfo->Effects[i].Effect)
6083 {
6085 {
6086 if (!m_caster->IsPlayer())
6088
6089 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6090 break;
6091
6092 Pet* pet = m_caster->ToPlayer()->GetPet();
6093
6094 if (!pet)
6095 return SPELL_FAILED_NO_PET;
6096
6097 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6098
6099 if (!learn_spellproto)
6101
6102 if (m_spellInfo->SpellLevel > pet->GetLevel())
6103 return SPELL_FAILED_LOWLEVEL;
6104
6105 break;
6106 }
6108 {
6109 // check target only for unit target case
6111 {
6112 if (!m_caster->IsPlayer())
6114
6115 Pet* pet = unitTarget->ToPet();
6116 if (!pet || pet->GetOwner() != m_caster)
6118
6119 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6120
6121 if (!learn_spellproto)
6123
6124 if (m_spellInfo->SpellLevel > pet->GetLevel())
6125 return SPELL_FAILED_LOWLEVEL;
6126 }
6127 break;
6128 }
6130 {
6131 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6132 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6133 if (m_caster->HasAura(gp->SpellId))
6135 break;
6136 }
6138 {
6139 if (!m_caster->IsPlayer())
6141
6142 Item* foodItem = m_targets.GetItemTarget();
6143 if (!foodItem)
6145
6146 Pet* pet = m_caster->ToPlayer()->GetPet();
6147
6148 if (!pet)
6149 return SPELL_FAILED_NO_PET;
6150
6151 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6153
6154 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6156
6157 if (m_caster->IsInCombat() || pet->IsInCombat())
6159
6160 break;
6161 }
6164 {
6165 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6166 if (m_caster->IsPlayer())
6167 if (Unit* target = m_targets.GetUnitTarget())
6168 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6170 break;
6171 }
6173 {
6175 {
6177 }
6178
6180 {
6181 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6182 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6184 }
6186 {
6187 // Exception for Master's Call
6188 if (m_spellInfo->Id != 54216)
6189 {
6190 return SPELL_FAILED_ROOTED;
6191 }
6192 }
6193 if (m_caster->IsPlayer())
6194 if (Unit* target = m_targets.GetUnitTarget())
6195 if (!target->IsAlive())
6197 // Xinef: Pass only explicit unit target spells
6198 // pussywizard:
6199 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6200 {
6201 Unit* target = m_targets.GetUnitTarget();
6202 if (!target)
6204
6205 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6206 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6208
6209 float objSize = target->GetCombatReach();
6210 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6211
6212 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6213 m_preGeneratedPath->SetPathLengthLimit(range);
6214
6215 // first try with raycast, if it fails fall back to normal path
6216 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6217 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6218 return SPELL_FAILED_NOPATH;
6219 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6220 return SPELL_FAILED_NOPATH;
6221 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6222 return SPELL_FAILED_NOPATH;
6223
6224 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6225 }
6226 if (Player* player = m_caster->ToPlayer())
6227 player->SetCanTeleport(true);
6228 break;
6229 }
6231 {
6234
6237
6238 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6239 if (!creature->IsCritter() && !creature->loot.isLooted())
6241
6242 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6243
6244 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6245 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6246 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6247 if (ReqValue > skillValue)
6249
6250 break;
6251 }
6253 {
6254 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6255 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6256 break;
6257
6258 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6259 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6260 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6262
6263 Item* pTempItem = nullptr;
6265 {
6266 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6267 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6268 }
6271
6272 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6273 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6275 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6277
6278 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6279 if (GameObject* go = m_targets.GetGOTarget())
6280 {
6281 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6282 {
6284 }
6285 }
6286 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6288 {
6289 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6290 {
6291 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6293 }
6294 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6297 }
6298
6299 // get the lock entry
6300 uint32 lockId = 0;
6301 if (GameObject* go = m_targets.GetGOTarget())
6302 {
6303 lockId = go->GetGOInfo()->GetLockId();
6304 if (!lockId)
6306 }
6307 else if (Item* itm = m_targets.GetItemTarget())
6308 lockId = itm->GetTemplate()->LockID;
6309
6310 SkillType skillId = SKILL_NONE;
6311 int32 reqSkillValue = 0;
6312 int32 skillValue = 0;
6313
6314 // check lock compatibility
6315 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6316 if (res != SPELL_CAST_OK)
6317 return res;
6318
6319 // chance for fail at lockpicking attempt
6320 // second check prevent fail at rechecks
6321 // herbalism and mining cannot fail as of patch 3.1.0
6322 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6323 {
6324 // chance for failure in orange lockpick
6325 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6326 {
6328 }
6329 }
6330 break;
6331 }
6333 {
6334 Unit* unitCaster = m_caster->ToUnit();
6335 if (!unitCaster)
6336 {
6338 }
6339
6340 Creature* pet = unitCaster->GetGuardianPet();
6341 if (pet)
6342 {
6343 if (pet->IsAlive())
6344 {
6346 }
6347 }
6348 else if (Player* playerCaster = m_caster->ToPlayer())
6349 {
6350 PetStable& petStable = playerCaster->GetOrInitPetStable();
6351 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6352 {
6353 return SPELL_FAILED_NO_PET;
6354 }
6355 }
6356
6357 break;
6358 }
6359 // This is generic summon effect
6361 {
6362 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6363 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6364 break;
6365 switch (SummonProperties->Category)
6366 {
6368 if (m_caster->GetPetGUID())
6370 [[fallthrough]];
6372 if (m_caster->GetCharmGUID())
6374 break;
6375 }
6376 break;
6377 }
6379 {
6381 {
6386 }
6387 break;
6388 }
6390 {
6391 Unit* unitCaster = m_caster->ToUnit();
6392 if (!unitCaster)
6394
6396 {
6397 if (m_caster->GetPetGUID())
6399 if (m_caster->GetCharmGUID())
6401 }
6402
6404 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6405 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6406
6407 Player* playerCaster = unitCaster->ToPlayer();
6408 if (playerCaster && playerCaster->GetPetStable())
6409 {
6410 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6411 if (info.first)
6412 {
6413 if (info.first->Type == HUNTER_PET)
6414 {
6415 if (!info.first->Health)
6416 {
6417 playerCaster->SendTameFailure(PET_TAME_DEAD);
6419 }
6420
6421 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6422 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6423 {
6424 // if problem in exotic pet
6425 if (creatureInfo && creatureInfo->IsTameable(true))
6427 else
6429
6431 }
6432 }
6433 }
6434 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6435 {
6438 }
6439 }
6440 break;
6441 }
6443 {
6444 if (!m_caster->IsPlayer())
6446 if (!m_caster->GetTarget())
6448
6450 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6452
6453 // Xinef: Implement summon pending error
6454 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6456
6457 // check if our map is dungeon
6458 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6459 if (map->IsDungeon())
6460 {
6461 uint32 mapId = m_caster->GetMap()->GetId();
6462 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6463 /*if (map->IsRaid())
6464 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6465 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6466 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6467
6468 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6469 if (!instance)
6471 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6473 }
6474 break;
6475 }
6476 // RETURN HERE
6478 {
6479 if (!m_caster->IsPlayer())
6481
6482 Player* playerCaster = m_caster->ToPlayer();
6483 //
6484 if (!(playerCaster->GetTarget()))
6486
6488
6489 if (!target ||
6490 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6492
6493 // Xinef: Implement summon pending error
6494 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6496
6497 break;
6498 }
6499 case SPELL_EFFECT_LEAP:
6501 {
6502 //Do not allow to cast it before BG starts.
6503 if (m_caster->IsPlayer())
6504 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6505 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6507 break;
6508 }
6510 {
6513
6514 bool found = false;
6516 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6517 {
6518 if (itr->second->GetBase()->IsPassive())
6519 continue;
6520
6521 if (!itr->second->IsPositive())
6522 continue;
6523
6524 found = true;
6525 break;
6526 }
6527
6528 if (!found)
6530
6531 break;
6532 }
6534 {
6536 {
6537 if (m_caster->IsPlayer())
6538 return SPELL_FAILED_ROOTED;
6539 else
6541 }
6542 break;
6543 }
6544 // xinef: do not allow to use leaps while rooted
6545 case SPELL_EFFECT_JUMP:
6547 {
6549 return SPELL_FAILED_ROOTED;
6550 break;
6551 }
6553 if (!sScriptMgr->CanSelectSpecTalent(this))
6555 // can't change during already started arena/battleground
6556 if (m_caster->IsPlayer())
6557 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6558 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6560 break;
6561 default:
6562 break;
6563 }
6564 }
6565
6566 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6567 {
6568 switch (m_spellInfo->Effects[i].ApplyAuraName)
6569 {
6570 case SPELL_AURA_DUMMY:
6571 break;
6573 {
6574 if (!m_caster->IsPlayer())
6575 return SPELL_FAILED_NO_PET;
6576
6577 Pet* pet = m_caster->ToPlayer()->GetPet();
6578 if (!pet)
6579 return SPELL_FAILED_NO_PET;
6580
6581 if (pet->GetCharmerGUID())
6582 return SPELL_FAILED_CHARMED;
6583 break;
6584 }
6588 {
6589 if (m_caster->GetCharmerGUID())
6590 return SPELL_FAILED_CHARMED;
6591
6592 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6594 {
6595 if (m_caster->GetPetGUID())
6597
6598 if (m_caster->GetCharmGUID())
6600 }
6601 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6602 {
6603 if (m_caster->GetCharmGUID())
6605 }
6606
6607 if (Unit* target = m_targets.GetUnitTarget())
6608 {
6609 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6611
6612 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6613 // but keep the old restriction for everything else.
6614 if (target->IsMounted())
6615 {
6616 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6618 }
6619
6620 if (target->GetCharmerGUID())
6621 return SPELL_FAILED_CHARMED;
6622
6623 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6625
6626 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6628
6629 int32 damage = CalculateSpellDamage(i, target);
6630 if (damage && int32(target->GetLevel()) > damage)
6632 }
6633
6634 break;
6635 }
6636 case SPELL_AURA_MOUNTED:
6637 {
6638 // Disallow casting flying mounts in water
6641
6642 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6643 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6644 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6645 if (it)
6646 allowMount = it->AllowMount;
6647 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6649
6652
6653 // xinef: dont allow to cast mounts in specific transforms
6654 if (m_caster->getTransForm())
6655 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6656 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6657 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6659
6660 break;
6661 }
6663 {
6664 if (!m_targets.GetUnitTarget())
6666
6667 // can be casted at non-friendly unit or own pet/charm
6670
6671 break;
6672 }
6673 case SPELL_AURA_FLY:
6675 {
6676 // Xinef: added water check
6677 if (m_caster->IsInWater())
6679
6680 // not allow cast fly spells if not have req. skills (all spells is self target)
6681 // allow always ghost flight spells
6683 {
6684 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6685 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6686 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6687 return SPELL_FAILED_NOT_HERE;
6688 }
6689 break;
6690 }
6692 {
6693 if (m_spellInfo->Effects[i].IsTargetingArea())
6694 break;
6695
6696 if (!m_caster->IsPlayer() || m_CastItem)
6697 break;
6698
6699 if (!m_targets.GetUnitTarget())
6701
6704
6705 break;
6706 }
6707 case SPELL_AURA_HOVER:
6708 {
6710 {
6712 }
6713 break;
6714 }
6716 {
6717 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6718 {
6720 }
6721 break;
6722 }
6723 default:
6724 break;
6725 }
6726 }
6727
6728 // check trade slot case (last, for allow catch any another cast problems)
6730 {
6731 if (m_CastItem)
6733
6734 if (!m_caster->IsPlayer())
6736
6737 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6738
6739 if (!my_trade)
6741
6743 if (slot != TRADE_SLOT_NONTRADED)
6745
6746 if (!IsTriggered())
6747 if (my_trade->GetSpell())
6749 }
6750
6751 // check if caster has at least 1 combo point on target for spells that require combo points
6753 {
6755 {
6757 {
6759 }
6760 }
6761 else
6762 {
6763 if (!m_caster->GetComboPoints())
6764 {
6766 }
6767 }
6768 }
6769
6770 // xinef: check relic cooldown
6774
6775 // all ok
6776 return SPELL_CAST_OK;
6777}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:291
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:141
std::list< Condition * > ConditionList
Definition ConditionMgr.h:238
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
Difficulty
Definition DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition DBCEnums.h:262
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:692
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:103
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:110
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:33
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:491
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1577
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
Powers
Definition SharedDefines.h:279
@ POWER_MANA
Definition SharedDefines.h:280
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:655
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:818
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:851
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:873
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:941
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:863
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:890
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:874
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:831
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:832
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:898
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:927
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:817
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:797
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:807
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:885
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:902
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:951
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:825
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:830
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:884
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:942
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:822
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:915
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:846
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1564
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:604
@ TARGET_UNIT_PET
Definition SharedDefines.h:1425
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1438
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:469
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:439
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:515
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3949
@ PET_TAME_DEAD
Definition SharedDefines.h:3952
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3954
@ CLASS_WARLOCK
Definition SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1410
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3798
SpellCustomErrors
Definition SharedDefines.h:1153
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1219
SpellAttr0
Definition SharedDefines.h:392
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:407
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:419
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:408
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:417
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:399
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:416
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:410
AuraStateType
Definition SharedDefines.h:1299
DispelType
Definition SharedDefines.h:1382
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1081
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:1021
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:1011
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1024
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:961
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:982
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1046
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1023
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:995
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:1020
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1063
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1095
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1132
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1143
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1106
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:971
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1092
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1038
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:967
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:968
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1031
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1047
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1043
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1126
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:1017
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:966
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1097
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:996
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1027
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1102
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1111
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:1002
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1055
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1078
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1048
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:973
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:983
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1115
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1142
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1146
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1086
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1028
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1136
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1053
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:984
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:1007
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1065
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1044
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:1016
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1067
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1050
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1025
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1075
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:558
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:557
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3535
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3536
SkillType
Definition SharedDefines.h:3113
@ SKILL_MINING
Definition SharedDefines.h:3169
@ SKILL_HERBALISM
Definition SharedDefines.h:3165
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:627
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:147
std::vector< SpellImmune > SpellImmuneList
Definition SpellDefines.h:182
@ TARGET_FLAG_UNIT_ENEMY
Definition SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:193
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:34
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:86
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:382
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:240
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:310
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:104
@ UNIT_STATE_ROOT
Definition UnitDefines.h:180
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:187
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:280
#define WORLD_TRIGGER
Definition Unit.h:39
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:79
Definition Battlefield.h:205
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition Battlefield.h:342
Definition Battleground.h:294
Loot loot
Definition Creature.h:229
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:208
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2846
Definition GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:169
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:544
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:295
bool IsBattlegroundOrArena() const
Definition Map.h:303
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2362
uint32 GetId() const
Definition Map.h:229
Difficulty GetDifficulty() const
Definition Map.h:290
uint64 GetRawValue() const
Definition ObjectGuid.h:142
bool IsPlayer() const
Definition ObjectGuid.h:168
bool IsGameObject() const
Definition ObjectGuid.h:171
Unit * ToUnit()
Definition Object.h:210
Definition PetDefines.h:212
Optional< PetInfo > CurrentPet
Definition PetDefines.h:235
std::vector< PetInfo > UnslottedPets
Definition PetDefines.h:238
Player * GetOwner() const
Definition Pet.cpp:2496
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1442
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1460
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition Pet.cpp:171
void SetCanTeleport(bool value)
Definition Player.h:2500
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1881
bool CanTameExoticPets() const
Definition Player.h:2187
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13216
bool InBattleground() const
Definition Player.h:2254
PetStable * GetPetStable()
Definition Player.h:1208
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12196
WorldSession * GetSession() const
Definition Player.h:1998
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16310
uint32 GetLastPotionId()
Definition Player.h:1807
Group * GetGroup()
Definition Player.h:2470
bool IsGameMaster() const
Definition Player.h:1161
time_t GetSummonExpireTimer() const
Definition Player.h:1103
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6719
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1110
std::unique_ptr< DuelInfo > duel
Definition Player.h:1873
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:408
GameObject * GetGOTarget() const
Definition Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:148
Definition SpellInfo.h:249
int32 MiscValue
Definition SpellInfo.h:263
uint32 ApplyAuraName
Definition SpellInfo.h:254
uint32 PreventionType
Definition SpellInfo.h:390
uint32 CasterAuraSpell
Definition SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1434
uint32 Mechanic
Definition SpellInfo.h:323
uint32 GetDispelMask() const
Definition SpellInfo.cpp:2052
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2408
bool IsSelfCast() const
Definition SpellInfo.cpp:1090
uint32 CasterAuraState
Definition SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1232
uint32 CasterAuraStateNot
Definition SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition SpellInfo.cpp:1489
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1998
int32 AreaGroupId
Definition SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2335
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:2066
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1033
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:345
uint32 SpellFamilyName
Definition SpellInfo.h:387
uint32 AuraInterruptFlags
Definition SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1948
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:791
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7726
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8339
SpellCastResult CheckItems()
Definition Spell.cpp:7143
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:488
SpellCastResult CheckPower()
Definition Spell.cpp:7098
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6815
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8547
bool IsTriggered() const
Definition Spell.h:564
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7012
bool HasGlobalCooldown() const
Definition Spell.cpp:8819
Definition TemporarySummon.h:40
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:783
Vehicle * GetVehicle() const
Definition Unit.h:1880
Unit * GetOwner() const
Definition Unit.cpp:10677
Pet * ToPet()
Definition Unit.h:714
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1302
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1911
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1303
bool IsInDisallowedMountForm() const
Definition Unit.cpp:21142
void CombatStart(Unit *target, bool initialAggro=true)
Definition Unit.cpp:13708
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:738
bool IsInSanctuary() const
Definition Unit.h:1021
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:827
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:5901
float GetCombatReach() const override
Definition Unit.h:860
UnitFlags GetUnitFlags() const
Definition Unit.h:731
TempSummon * ToTempSummon()
Definition Unit.h:716
bool HasStealthAura() const
Definition Unit.h:1796
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5790
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:672
bool IsInFlight() const
Definition Unit.h:1660
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2047
void SendTameFailure(uint8 result)
Definition Unit.cpp:19757
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5674
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:759
virtual bool IsInWater() const
Definition Unit.cpp:4408
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:10624
bool isMoving() const
Definition Unit.h:1663
ObjectGuid GetCharmGUID() const
Definition Unit.h:706
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1498
bool IsMounted() const
Definition Unit.h:1841
Unit * GetVictim() const
Definition Unit.h:886
bool IsCritter() const
Definition Unit.h:816
ObjectGuid GetOwnerGUID() const
Definition Unit.h:698
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:992
ObjectGuid GetCharmerGUID() const
Definition Unit.h:704
uint32 getTransForm() const
Definition Unit.h:1922
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1094
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5303
bool IsTotem() const
Definition Unit.h:782
Guardian * GetGuardianPet() const
Definition Unit.cpp:10728
ObjectGuid GetTarget() const
Definition Unit.h:844
bool IsInCombat() const
Definition Unit.h:917
ObjectGuid GetPetGUID() const
Definition Unit.h:708
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:600
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:621
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1221
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition Object.cpp:1380
bool IsOutdoors() const
Definition Object.cpp:3088
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1359
float GetVisibilityRange() const
Definition Object.cpp:1678
uint32 GetAreaId() const
Definition Object.cpp:3071
uint32 GetZoneId() const
Definition Object.cpp:3063
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3079
uint32 GetRecruiterId() const
Definition WorldSession.h:588
uint32 GetAccountId() const
Definition WorldSession.h:423
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition DBCStructure.h:519
Definition ConditionMgr.h:183
Condition * mLastFailedCondition
Definition ConditionMgr.h:185
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:184
uint32 ErrorType
Definition ConditionMgr.h:206
uint8 ConditionTarget
Definition ConditionMgr.h:210
uint32 ErrorTextId
Definition ConditionMgr.h:207
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:257
bool IsTameable(bool exotic) const
Definition CreatureData.h:274
uint32 type
Definition GameObjectData.h:33
Definition DBCStructure.h:1022
Definition Map.h:121
bool AllowMount
Definition Map.h:124
uint32 ItemLevel
Definition ItemTemplate.h:635
uint32 LockID
Definition ItemTemplate.h:669
uint32 InventoryType
Definition ItemTemplate.h:632
bool isLooted() const
Definition LootMgr.h:368
Definition DBCStructure.h:1326
bool IsDungeon() const
Definition DBCStructure.h:1352
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1818
uint32 flags1
Definition DBCStructure.h:1823
Definition DBCStructure.h:1910
uint32 Category
Definition DBCStructure.h:1912
Definition DBCStructure.h:2065
uint32 m_flags
Definition DBCStructure.h:2067

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, Unit::CastSpell(), SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, sDisableMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SHAPESHIFT_FLAG_STANCE, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6816{
6817 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6819 return SPELL_CAST_OK;
6820
6821 uint8 school_immune = 0;
6822 uint32 mechanic_immune = 0;
6823 uint32 dispel_immune = 0;
6824
6825 // Check if the spell grants school or mechanic immunity.
6826 // We use bitmasks so the loop is done only once and not on every aura check below.
6828 {
6829 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6830 {
6831 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6832 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6833 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6834 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6835 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6836 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6837 }
6838 // immune movement impairment and loss of control
6839 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6840 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6842 }
6843
6845
6846 // Glyph of Pain Suppression
6847 // there is no other way to handle it
6848 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6849 usableInStun = false;
6850
6851 // Check whether the cast should be prevented by any state you might have.
6852 SpellCastResult prevented_reason = SPELL_CAST_OK;
6853 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6854 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6855
6856 // Xinef: if spell is triggered check preventionType only
6857 if (!preventionOnly)
6858 {
6859 if (unitflag & UNIT_FLAG_STUNNED)
6860 {
6861 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6862 if (usableInStun)
6863 {
6864 bool foundNotStun = false;
6865 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6866 // Barkskin should skip sleep effects, sap and fears
6867 if (m_spellInfo->Id == 22812)
6868 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6869 // Hand of Freedom, can be used while sapped
6870 if (m_spellInfo->Id == 1044)
6871 mask |= 1 << MECHANIC_SAPPED;
6873 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6874 {
6875 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6876 {
6877 foundNotStun = true;
6878 break;
6879 }
6880 }
6881 if (foundNotStun)
6882 prevented_reason = SPELL_FAILED_STUNNED;
6883 }
6884 else
6885 prevented_reason = SPELL_FAILED_STUNNED;
6886 }
6888 prevented_reason = SPELL_FAILED_CONFUSED;
6890 prevented_reason = SPELL_FAILED_FLEEING;
6891 }
6892
6893 // Xinef: if there is no prevented_reason, check prevention types
6894 if (prevented_reason == SPELL_CAST_OK)
6895 {
6897 prevented_reason = SPELL_FAILED_SILENCED;
6899 prevented_reason = SPELL_FAILED_PACIFIED;
6900 }
6901
6902 // Attr must make flag drop spell totally immune from all effects
6903 if (prevented_reason != SPELL_CAST_OK)
6904 {
6905 if (school_immune || mechanic_immune || dispel_immune)
6906 {
6907 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6909 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6910 {
6911 Aura const* aura = itr->second->GetBase();
6912 SpellInfo const* auraInfo = aura->GetSpellInfo();
6913 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6914 continue;
6915 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6916 continue;
6917 if (auraInfo->GetDispelMask() & dispel_immune)
6918 continue;
6919
6920 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6921 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6922 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6923 {
6924 if (AuraEffect* part = aura->GetEffect(i))
6925 {
6926 switch (part->GetAuraType())
6927 {
6929 {
6930 uint32 mask = 1 << MECHANIC_STUN;
6931 // Barkskin should skip sleep effects, sap and fears
6932 if (m_spellInfo->Id == 22812)
6933 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6934 // Hand of Freedom, can be used while sapped
6935 if (m_spellInfo->Id == 1044)
6936 mask |= 1 << MECHANIC_SAPPED;
6937
6938 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6939 return SPELL_FAILED_STUNNED;
6940 break;
6941 }
6944 return SPELL_FAILED_CONFUSED;
6945 break;
6948 return SPELL_FAILED_FLEEING;
6949 break;
6954 return SPELL_FAILED_PACIFIED;
6956 return SPELL_FAILED_SILENCED;
6957 break;
6958 default:
6959 break;
6960 }
6961 }
6962 }
6963 }
6964 }
6965 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6966 else
6967 return prevented_reason;
6968 }
6969 return SPELL_CAST_OK;
6970}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1565
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1566
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:581
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:595
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:596
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:445
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:446
@ MECHANIC_STUN
Definition SharedDefines.h:1348
@ MECHANIC_FREEZE
Definition SharedDefines.h:1349
@ MECHANIC_SLEEP
Definition SharedDefines.h:1346
@ MECHANIC_SAPPED
Definition SharedDefines.h:1366
@ MECHANIC_HORROR
Definition SharedDefines.h:1360
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1372
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1068
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:986
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1064
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:994
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1058
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:617
@ SPELL_AURA_DISPEL_IMMUNITY
Definition SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:272
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:271
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:276
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:277
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:267
Definition SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:2003
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:659
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1346

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:406

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8481{
8482 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8484}
#define ASSERT
Definition Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7904{
7905 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7906 {
7911 if (target->IsCreature() && target->IsVehicle())
7912 return false;
7913 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
7914 return false;
7915 if (target->GetCharmerGUID())
7916 return false;
7917 if (int32 damage = CalculateSpellDamage(eff, target))
7918 if ((int32)target->GetLevel() > damage)
7919 return false;
7920 break;
7921 default:
7922 break;
7923 }
7924
7925 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7926 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7927 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7928 return true;
7929
7930 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7933 {
7934 return true;
7935 }
7936
7938 //Check targets for LOS visibility (except spells without range limitations)
7939 switch (m_spellInfo->Effects[eff].Effect)
7940 {
7942 // player far away, maybe his corpse near?
7943 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7944 {
7946 return false;
7947
7949 if (!corpse)
7950 return false;
7951
7952 if (target->GetGUID() != corpse->GetOwnerGUID())
7953 return false;
7954
7956 return false;
7957 }
7958 break;
7960 {
7962 {
7963 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7964 return true;
7965
7966 return false;
7967 }
7968
7970 if (!corpse)
7971 return false;
7972
7973 if (target->GetGUID() != corpse->GetOwnerGUID())
7974 return false;
7975
7977 return false;
7978
7980 return false;
7981 }
7982 break;
7984 if (!m_caster->IsPlayer() || !target->IsPlayer())
7985 return false;
7986 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7987 return false;
7988 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
7989 return false;
7990 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
7991 return false;
7992 break;
7993 default: // normal case
7994 {
7995 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
7996 GameObject* gobCaster = nullptr;
7998 {
8000 }
8001 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8002 {
8003 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8004 {
8005 gobCaster = tempSummon->GetSummonerGameObject();
8006 }
8007 }
8008
8009 if (gobCaster)
8010 {
8011 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8012 {
8013 return true;
8014 }
8015
8016 // If spell casted by gameobject then ignore M2 models
8017 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8018 }
8019
8020 if (target != m_caster)
8021 {
8022 if (m_targets.HasDst())
8023 {
8024 float x = m_targets.GetDstPos()->GetPositionX();
8025 float y = m_targets.GetDstPos()->GetPositionY();
8026 float z = m_targets.GetDstPos()->GetPositionZ();
8027
8028 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8029 {
8030 return false;
8031 }
8032 }
8034 {
8035 return false;
8036 }
8037 }
8038 break;
8039 }
8040 }
8041
8042 return true;
8043}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:905
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:115
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:279
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:200
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:878
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:281
bool IsARecruiter() const
Definition WorldSession.h:589
#define sWorld
Definition World.h:316
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:179
bool IsIgnoringLOSChecks() const
Definition GameObjectData.h:644

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, sDisableMgr, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7144{
7145 Player* player = m_caster->ToPlayer();
7146 if (!player)
7147 {
7148 // Non-player case: Check if creature is disarmed
7150 {
7152 }
7153
7154 return SPELL_CAST_OK;
7155 }
7156
7157 if (!m_CastItem)
7158 {
7159 if (m_castItemGUID)
7161 }
7162 else
7163 {
7164 uint32 itemid = m_CastItem->GetEntry();
7165 if (!player->HasItemCount(itemid))
7167
7168 ItemTemplate const* proto = m_CastItem->GetTemplate();
7169 if (!proto)
7171
7172 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7173 if (proto->Spells[i].SpellCharges)
7174 if (m_CastItem->GetSpellCharges(i) == 0)
7176
7177 // consumable cast item checks
7179 {
7180 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7181 SpellCastResult failReason = SPELL_CAST_OK;
7182 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7183 {
7184 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7185 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7186 continue;
7187
7188 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7189 {
7191 {
7193 continue;
7194 }
7195 else
7196 {
7197 failReason = SPELL_CAST_OK;
7198 break;
7199 }
7200 }
7201
7202 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7203 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7204 {
7205 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7206 {
7208 continue;
7209 }
7210
7211 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7213 {
7215 continue;
7216 }
7217 else
7218 {
7219 failReason = SPELL_CAST_OK;
7220 break;
7221 }
7222 }
7223 }
7224 if (failReason != SPELL_CAST_OK)
7225 return failReason;
7226 }
7227 }
7228
7229 // check target item
7231 {
7232 if (!m_caster->IsPlayer())
7234
7235 if (!m_targets.GetItemTarget())
7237
7240 }
7241 // if not item target then required item must be equipped
7242 else
7243 {
7244 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7245 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7248 }
7249
7250 // do not take reagents for these item casts
7252 {
7254 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7255 if (!checkReagents)
7256 if (Item* targetItem = m_targets.GetItemTarget())
7257 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7258 checkReagents = true;
7259
7260 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7261 if (checkReagents)
7262 {
7263 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7264 {
7265 if (m_spellInfo->Reagent[i] <= 0)
7266 continue;
7267
7268 uint32 itemid = m_spellInfo->Reagent[i];
7269 uint32 itemcount = m_spellInfo->ReagentCount[i];
7270
7271 // if CastItem is also spell reagent
7272 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7273 {
7274 ItemTemplate const* proto = m_CastItem->GetTemplate();
7275 if (!proto)
7277 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7278 {
7279 // CastItem will be used up and does not count as reagent
7280 int32 charges = m_CastItem->GetSpellCharges(s);
7281 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7282 {
7283 ++itemcount;
7284 break;
7285 }
7286 }
7287 }
7288 if (!player->HasItemCount(itemid, itemcount))
7289 return SPELL_FAILED_REAGENTS;
7290 }
7291 }
7292
7293 // check totem-item requirements (items presence in inventory)
7294 uint32 totems = 2;
7295 for (int i = 0; i < 2; ++i)
7296 {
7297 if (m_spellInfo->Totem[i] != 0)
7298 {
7299 if (player->HasItemCount(m_spellInfo->Totem[i]))
7300 {
7301 totems -= 1;
7302 continue;
7303 }
7304 }
7305 else
7306 totems -= 1;
7307 }
7308 if (totems != 0)
7309 return SPELL_FAILED_TOTEMS; //0x7C
7310
7311 // Check items for TotemCategory (items presence in inventory)
7313 for (int i = 0; i < 2; ++i)
7314 {
7315 if (m_spellInfo->TotemCategory[i] != 0)
7316 {
7318 {
7319 TotemCategory -= 1;
7320 continue;
7321 }
7322 }
7323 else
7324 TotemCategory -= 1;
7325 }
7326 if (TotemCategory != 0)
7327 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7328 }
7329
7330 // special checks for spell effects
7331 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7332 {
7333 switch (m_spellInfo->Effects[i].Effect)
7334 {
7337 {
7338 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7339 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7340 if (target->IsPlayer() && !IsTriggered())
7341 {
7342 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7343 // so we need to make sure there is at least one free space in the player's inventory
7345 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7346 {
7347 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7349 }
7350
7351 if (m_spellInfo->Effects[i].ItemType)
7352 {
7353 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7354 if (!itemTemplate)
7356
7357 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7358 ItemPosCountVec dest;
7359 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7360 if (msg != EQUIP_ERR_OK)
7361 {
7363 if (!itemTemplate->ItemLimitCategory)
7364 {
7365 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7367 }
7368 else
7369 {
7370 // Conjure Food/Water/Refreshment spells
7373 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7374 {
7375 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7377 }
7378 else
7379 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7380
7382 }
7383 }
7384 }
7385 }
7386 break;
7387 }
7389 {
7390 if (player->GetFreeInventorySpace() == 0)
7391 {
7392 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7394 }
7395 break;
7396 }
7398 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7400 {
7401 // cannot enchant vellum for other player
7404 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7407 ItemPosCountVec dest;
7408 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7409 if (msg != EQUIP_ERR_OK)
7410 {
7411 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7413 }
7414 }
7415 [[fallthrough]];
7417 {
7418 Item* targetItem = m_targets.GetItemTarget();
7419 if (!targetItem)
7421
7422 // Apply item level restriction
7424 {
7425 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7426 if (!requiredLevel)
7427 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7428
7429 if (requiredLevel < m_spellInfo->BaseLevel)
7430 return SPELL_FAILED_LOWLEVEL;
7431 }
7432
7433 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7435
7436 bool isItemUsable = false;
7437 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7438 {
7439 ItemTemplate const* proto = targetItem->GetTemplate();
7440 if (proto->Spells[e].SpellId && (
7443 {
7444 isItemUsable = true;
7445 break;
7446 }
7447 }
7448
7449 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7450 // do not allow adding usable enchantments to items that have use effect already
7451 if (enchantEntry)
7452 {
7453 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7454 {
7455 switch (enchantEntry->type[s])
7456 {
7458 if (isItemUsable)
7460 break;
7462 {
7463 uint32 numSockets = 0;
7464 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7465 if (targetItem->GetTemplate()->Socket[socket].Color)
7466 ++numSockets;
7467
7468 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7470 break;
7471 }
7472 }
7473 }
7474 }
7475
7476 // Not allow enchant in trade slot for some enchant type
7477 if (targetItem->GetOwner() != m_caster)
7478 {
7479 if (!enchantEntry)
7480 return SPELL_FAILED_ERROR;
7481 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7483 }
7484 break;
7485 }
7487 {
7488 Item* item = m_targets.GetItemTarget();
7489 if (!item)
7491 // Not allow enchant in trade slot for some enchant type
7492 if (item->GetOwner() != m_caster)
7493 {
7494 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7495 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7496 if (!pEnchant)
7497 return SPELL_FAILED_ERROR;
7498 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7500 }
7501
7502 // Apply item level restriction
7504 {
7505 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7506 if (!requiredLevel)
7507 requiredLevel = item->GetTemplate()->ItemLevel;
7508
7509 if (requiredLevel < m_spellInfo->BaseLevel)
7510 return SPELL_FAILED_LOWLEVEL;
7511 }
7512
7515
7516 break;
7517 }
7519 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7520 break;
7522 {
7523 if (!m_targets.GetItemTarget())
7525
7526 // prevent disenchanting in trade slot
7529
7530 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7531 if (!itemProto)
7533
7534 uint32 item_quality = itemProto->Quality;
7535 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7536 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7537 if (item_disenchantskilllevel == uint32(-1))
7539 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7541 if (item_quality > 4 || item_quality < 2)
7543 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7545 if (!itemProto->DisenchantID)
7547 break;
7548 }
7550 {
7551 if (!m_targets.GetItemTarget())
7553 //ensure item is a prospectable ore
7556 //prevent prospecting in trade slot
7559 //Check for enough skill in jewelcrafting
7560 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7561 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7563 //make sure the player has the required ores in inventory
7564 if (m_targets.GetItemTarget()->GetCount() < 5)
7566
7569
7570 break;
7571 }
7573 {
7574 if (!m_targets.GetItemTarget())
7576 //ensure item is a millable herb
7579 //prevent milling in trade slot
7582 //Check for enough skill in inscription
7583 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7584 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7586 //make sure the player has the required herbs in inventory
7587 if (m_targets.GetItemTarget()->GetCount() < 5)
7589
7592
7593 break;
7594 }
7597 {
7598 if (!m_caster->IsPlayer())
7600
7602 break;
7603
7605 if (!pItem || pItem->IsBroken())
7607
7608 switch (pItem->GetTemplate()->SubClass)
7609 {
7611 {
7612 uint32 ammo = pItem->GetEntry();
7613 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7614 return SPELL_FAILED_NO_AMMO;
7615 };
7616 break;
7620 {
7622 if (!ammo)
7623 {
7624 // Requires No Ammo
7625 if (m_caster->HasAura(46699))
7626 break; // skip other checks
7627
7628 return SPELL_FAILED_NO_AMMO;
7629 }
7630
7631 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7632 if (!ammoProto)
7633 return SPELL_FAILED_NO_AMMO;
7634
7635 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7636 return SPELL_FAILED_NO_AMMO;
7637
7638 // check ammo ws. weapon compatibility
7639 switch (pItem->GetTemplate()->SubClass)
7640 {
7643 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7644 return SPELL_FAILED_NO_AMMO;
7645 break;
7647 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7648 return SPELL_FAILED_NO_AMMO;
7649 break;
7650 default:
7651 return SPELL_FAILED_NO_AMMO;
7652 }
7653
7654 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7655 {
7657 return SPELL_FAILED_NO_AMMO;
7658 }
7659 };
7660 break;
7662 break;
7663 default:
7664 break;
7665 }
7666 break;
7667 }
7669 {
7670 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7671 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7672
7673 if (!pProto)
7675
7676 if (Item* pitem = player->GetItemByEntry(item_id))
7677 {
7678 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7679 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7681 }
7682 break;
7683 }
7684 default:
7685 break;
7686 }
7687 }
7688
7689 // check weapon presence in slots for main/offhand weapons
7690 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7691 {
7692 // main hand weapon required
7694 {
7696
7697 // skip spell if no weapon in slot or broken
7698 if (!item || item->IsBroken())
7700
7701 // skip spell if weapon not fit to triggered spell
7704 }
7705
7706 // offhand hand weapon required
7708 {
7710
7711 // skip spell if no weapon in slot or broken
7712 if (!item || item->IsBroken())
7714
7715 // skip spell if weapon not fit to triggered spell
7718 }
7719
7721 }
7722
7723 return SPELL_CAST_OK;
7724}
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:374
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_SPELL_REAGENTS
Definition DBCStructure.h:1640
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1839
std::int8_t int8
Definition Define.h:105
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition ItemTemplate.h:291
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
#define MAX_ITEM_SPELLS
Definition Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition Item.h:201
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition Item.h:175
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:766
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:287
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:888
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:916
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:881
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:842
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:847
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:799
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:947
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:855
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:946
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:806
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:819
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:848
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:945
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:843
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:813
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:470
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:514
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3797
TotemCategory
Definition SharedDefines.h:3333
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:976
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:991
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:989
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1139
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1082
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:964
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1030
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:1005
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1036
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:1003
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1035
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:1004
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:988
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:962
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1130
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1091
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:992
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1060
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1144
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:974
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1089
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:1015
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:977
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:990
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1090
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3252
@ SKILL_ENCHANTING
Definition SharedDefines.h:3204
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3235
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:338
bool IsArmorVellum() const
Definition Item.h:339
Player * GetOwner() const
Definition Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:884
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:294
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12518
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:467
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3368
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:656
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:852
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12563
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4020
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1280
uint32 GetItemTargetEntry() const
Definition Spell.h:150
uint32 MaxLevel
Definition SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition SpellInfo.h:373
flag96 SpellFamilyFlags
Definition SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition SpellInfo.h:378
int32 EquippedItemClass
Definition SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition SpellInfo.h:374
ObjectGuid m_castItemGUID
Definition Spell.h:534
bool IsFullHealth() const
Definition Unit.h:1076
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:970
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1098
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:21197
uint32 GetPower(Powers power) const
Definition Unit.h:1097
Definition ItemTemplate.h:619
uint32 DisenchantID
Definition ItemTemplate.h:690
uint32 Quality
Definition ItemTemplate.h:626
uint32 RequiredSkillRank
Definition ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition ItemTemplate.h:727
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684
uint32 RequiredLevel
Definition ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
uint32 Class
Definition ItemTemplate.h:621
uint32 ItemLimitCategory
Definition ItemTemplate.h:687
uint32 SubClass
Definition ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition ItemTemplate.h:681
Definition DBCStructure.h:1842
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1845
uint32 slot
Definition DBCStructure.h:1852
uint32 Color
Definition ItemTemplate.h:602
int32 SpellCharges
Definition ItemTemplate.h:593
uint32 SpellTrigger
Definition ItemTemplate.h:592
int32 SpellId
Definition ItemTemplate.h:591

References BASE_ATTACK, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6780{
6781 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6783
6784 // dead owner (pets still alive when owners ressed?)
6785 if (Unit* owner = m_caster->GetCharmerOrOwner())
6786 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6788
6789 if (!target && m_targets.GetUnitTarget())
6790 target = m_targets.GetUnitTarget();
6791
6793 {
6794 if (!target)
6796 m_targets.SetUnitTarget(target);
6797 }
6798
6799 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6801
6802 // cooldown
6803 if (Creature const* creatureCaster = m_caster->ToCreature())
6804 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6806
6807 // Check if spell is affected by GCD
6811
6812 return CheckCast(true);
6813}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2413
uint32 StartRecoveryCategory
Definition SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7099{
7100 // item cast not used power
7101 if (m_CastItem)
7102 return SPELL_CAST_OK;
7103
7104 //While .cheat power is enabled dont check if we need power to cast the spell
7105 if (m_caster->IsPlayer())
7106 {
7108 {
7109 return SPELL_CAST_OK;
7110 }
7111 }
7112
7113 // health as power used - need check health amount
7115 {
7118 return SPELL_CAST_OK;
7119 }
7120 // Check valid power type
7122 {
7123 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7124 return SPELL_FAILED_UNKNOWN;
7125 }
7126
7127 //check rune cost only if a spell has PowerType == POWER_RUNE
7129 {
7131 if (failReason != SPELL_CAST_OK)
7132 return failReason;
7133 }
7134
7135 // Check power amount
7138 return SPELL_FAILED_NO_POWER;
7139 else
7140 return SPELL_CAST_OK;
7141}
@ CHEAT_POWER
Definition Player.h:997
@ POWER_HEALTH
Definition SharedDefines.h:289
@ POWER_RUNE
Definition SharedDefines.h:285
@ SPELL_FAILED_NO_POWER
Definition SharedDefines.h:1045
@ SPELL_FAILED_UNKNOWN
Definition SharedDefines.h:1147
PowerType
Definition VehicleDefines.h:29
uint32 RuneCostID
Definition SpellInfo.h:368
uint32 PowerType
Definition SpellInfo.h:362
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition Spell.cpp:5368
uint32 GetHealth() const
Definition Unit.h:1070

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7013{
7014 // Don't check for instant cast spells
7015 if (!strict && m_casttime == 0)
7016 return SPELL_CAST_OK;
7017
7018 uint32 range_type = 0;
7019
7021 {
7022 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7023 // these are triggered by other spells - possibly we should omit range check in that case?
7024 if (m_spellInfo->RangeEntry->ID == 1)
7025 return SPELL_CAST_OK;
7026
7027 range_type = m_spellInfo->RangeEntry->Flags;
7028 }
7029
7030 Unit* target = m_targets.GetUnitTarget();
7031 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7032 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7033
7034 // xinef: hack for npc shooters
7035 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7036 range_type = SPELL_RANGE_RANGED;
7037
7038 if (Player* modOwner = m_caster->GetSpellModOwner())
7039 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7040
7041 // xinef: dont check max_range to strictly after cast
7042 if (range_type != SPELL_RANGE_MELEE && !strict)
7043 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7044
7045 if (target)
7046 {
7047 if (target != m_caster)
7048 {
7049 // Xinef: Spells with 5yd range can hit target 9yd away?
7050 if (range_type == SPELL_RANGE_MELEE)
7051 {
7052 float real_max_range = max_range;
7054 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7055 else
7056 real_max_range -= 2 * MIN_MELEE_REACH;
7057
7058 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7060 }
7061 else if (!m_caster->IsWithinCombatRange(target, max_range))
7062 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7063
7065 {
7066 if (m_caster->IsWithinMeleeRange(target))
7068 }
7069
7070 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7072 }
7073
7074 // Xinef: check min range for self casts
7075 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7077 }
7078
7079 if (GameObject* goTarget = m_targets.GetGOTarget())
7080 {
7081 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7082 {
7084 }
7085 }
7086
7087 if (m_targets.HasDst() && !m_targets.HasTraj())
7088 {
7089 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7091 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7093 }
7094
7095 return SPELL_CAST_OK;
7096}
#define MIN_MELEE_REACH
Definition ObjectDefines.h:46
@ SPELL_FAILED_TOO_CLOSE
Definition SharedDefines.h:1088
@ SPELL_FAILED_OUT_OF_RANGE
Definition SharedDefines.h:1057
@ SPELLMOD_RANGE
Definition SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:128
@ SPELL_RANGE_MELEE
Definition Spell.h:92
@ SPELL_RANGE_RANGED
Definition Spell.h:93
SpellRangeEntry const * RangeEntry
Definition SpellInfo.h:369
uint32 FacingCasterFlags
Definition SpellInfo.h:338
Unit * GetCaster() const
Definition Spell.h:585
bool IsWithinBoundaryRadius(const Unit *obj) const
Definition Unit.cpp:704
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15197
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:15177
bool HasLeewayMovement() const
Definition Unit.h:1684
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1328
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition Position.cpp:148
uint32 Flags
Definition DBCStructure.h:1798
uint32 ID
Definition DBCStructure.h:1795

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), Unit::HasLeewayMovement(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Object::IsPlayer(), Unit::IsWithinBoundaryRadius(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5369{
5370 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5371 return SPELL_CAST_OK;
5372
5373 if (!m_caster->IsPlayer())
5374 return SPELL_CAST_OK;
5375
5376 Player* player = m_caster->ToPlayer();
5377 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5378 if (player->GetCommandStatus(CHEAT_POWER))
5379 {
5380 return SPELL_CAST_OK;
5381 }
5382
5384 return SPELL_CAST_OK;
5385
5386 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5387
5388 if (!src)
5389 return SPELL_CAST_OK;
5390
5391 if (src->NoRuneCost())
5392 return SPELL_CAST_OK;
5393
5394 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5395
5396 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5397 {
5398 runeCost[i] = src->RuneCost[i];
5399 if (Player* modOwner = m_caster->GetSpellModOwner())
5400 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5401 }
5402
5403 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5404
5405 for (uint32 i = 0; i < MAX_RUNES; ++i)
5406 {
5407 RuneType rune = player->GetCurrentRune(i);
5408 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5409 runeCost[rune]--;
5410 }
5411
5412 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5413 if (runeCost[i] > 0)
5414 runeCost[RUNE_DEATH] += runeCost[i];
5415
5416 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5417 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5418
5419 return SPELL_CAST_OK;
5420}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition Player.h:404
@ RUNE_DEATH
Definition Player.h:408
@ NUM_RUNE_TYPES
Definition Player.h:409
#define MAX_RUNES
Definition Player.h:394
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ SPELLMOD_COST
Definition SpellDefines.h:90
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:238
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2510
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1301
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2509
Definition DBCStructure.h:1806
uint32 RuneCost[3]
Definition DBCStructure.h:1808
bool NoRuneCost() const
Definition DBCStructure.h:1811

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8702{
8703 // Skip if there are not any script
8704 if (!m_loadedScripts.size())
8705 return true;
8706
8707 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8708 {
8709 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8710 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8711 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8712 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8713 return false;
8714
8715 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8716 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8717 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8718 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8719 return false;
8720 }
8721 return true;
8722}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7727{
7728 // check spell focus object
7730 {
7732 Cell cell(p);
7733
7734 GameObject* ok = nullptr;
7737
7739 Map& map = *m_caster->GetMap();
7740 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7741
7742 if (!ok)
7744
7745 focusObject = ok; // game object found in range
7746 }
7747 return SPELL_CAST_OK;
7748}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1062
Definition GridNotifiers.h:648
Definition Map.h:163
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:700
uint32 RequiresSpellFocus
Definition SpellInfo.h:337
Definition TypeContainerVisitor.h:105
Definition TypeContainer.h:118
CellCoord ComputeCellCoord(float x, float y)
Definition GridDefines.h:197
Definition GridNotifiers.h:310
Definition Cell.h:45

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition Spell.h:174
void SetSrc(float x, float y, float z)
Definition Spell.cpp:367

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2285{
2286 m_UniqueTargetInfo.clear();
2287 m_UniqueGOTargetInfo.clear();
2288 m_UniqueItemInfo.clear();
2289 m_delayMoment = 0;
2291}
uint64 m_delayTrajectory
Definition Spell.h:652

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7751{
7752 if (!m_caster)// || !m_caster->IsPlayer())
7753 return;
7754
7755 //if (m_spellState == SPELL_STATE_DELAYED)
7756 // return; // spell is active and can't be time-backed
7757
7758 if (isDelayableNoMore()) // Spells may only be delayed twice
7759 return;
7760
7762 return;
7763
7764 // spells not loosing casting time (slam, dynamites, bombs..)
7765 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7766 // return;
7767
7768 //check pushback reduce
7769 int32 delaytime = 500; // spellcasting delay is normally 500ms
7770 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7773 if (delayReduce >= 100)
7774 return;
7775
7776 AddPct(delaytime, -delayReduce);
7777
7778 if (m_timer + delaytime > m_casttime)
7779 {
7780 delaytime = m_casttime - m_timer;
7782 }
7783 else
7784 m_timer += delaytime;
7785
7786 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7787
7788 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7789 data << m_caster->GetPackGUID();
7790 data << uint32(delaytime);
7791
7792 m_caster->SendMessageToSet(&data, true);
7793}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:630
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:67
PackedGuid const & GetPackGUID() const
Definition Object.h:115
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9775
bool isDelayableNoMore()
Definition Spell.h:640
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6010
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2090
Definition WorldPacket.h:26
@ SMSG_SPELL_DELAYED
Definition Opcodes.h:512

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7796{
7798 return;
7799
7800 if (isDelayableNoMore()) // Spells may only be delayed twice
7801 return;
7802
7804 return;
7805
7806 //check pushback reduce
7807 // should be affected by modifiers, not take the dbc duration.
7808 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7809
7810 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7811 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7814 if (delayReduce >= 100)
7815 return;
7816
7817 AddPct(delaytime, -delayReduce);
7818
7819 if (m_timer <= delaytime)
7820 {
7821 delaytime = m_timer;
7822 m_timer = 0;
7823 }
7824 else
7825 m_timer -= delaytime;
7826
7827 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7828
7829 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7830 if ((*ihit).missCondition == SPELL_MISS_NONE)
7831 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7832 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7833
7834 // partially interrupt persistent area auras
7836 dynObj->Delay(delaytime);
7837
7839}
T CalculatePct(T base, U pct)
Definition Util.h:61
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:493
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6228

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8279{
8280 Unit* unit = nullptr;
8281 // In case spell hit target, do all effect on that target
8282 if (targetInfo.missCondition == SPELL_MISS_NONE)
8283 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8284 // In case spell reflect from target, do all effect on caster (if hit)
8285 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8286 unit = m_caster;
8287 if (!unit)
8288 return;
8289
8290 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8291 {
8292 if (targetInfo.effectMask & (1 << i))
8293 {
8294 m_damage = 0;
8295 m_healing = 0;
8296
8297 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8298
8299 if (m_damage > 0)
8300 {
8301 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8302 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8303 {
8306 if (m_caster->IsPlayer())
8307 {
8308 uint32 targetAmount = m_UniqueTargetInfo.size();
8309 if (targetAmount > 10)
8310 m_damage = m_damage * 10 / targetAmount;
8311 }
8312 }
8313 }
8314
8315 if (m_applyMultiplierMask & (1 << i))
8316 {
8318 m_damageMultipliers[i] *= multiplier[i];
8319 }
8320 targetInfo.damage += m_damage;
8321 }
8322 }
8323
8324 // xinef: totem's inherit owner crit chance and dancing rune weapon
8325 Unit* caster = m_caster;
8326 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8327 {
8328 if (Unit* owner = m_caster->GetOwner())
8329 caster = owner;
8330 }
8331 else if (m_originalCaster)
8332 caster = m_originalCaster;
8333
8334 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8335 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8336 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8337}
bool roll_chance_f(float chance)
Definition Random.h:57
@ SPELL_ATTR7_TREAT_AS_NPC_AOE
Definition SharedDefines.h:678
uint32 SchoolMask
Definition SpellInfo.h:392
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12148
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:12073
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:20152

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), GetSpellInfo(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), Unit::IsControlledByPlayer(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_ATTR7_TREAT_AS_NPC_AOE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3278{
3279 if (target->processed) // Check target
3280 return;
3281 target->processed = true; // Target checked in apply effects procedure
3282
3283 uint32 effectMask = target->effectMask;
3284 if (!effectMask)
3285 return;
3286
3287 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3288 if (!go)
3289 return;
3290
3293
3294 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3295 if (effectMask & (1 << effectNumber))
3296 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3297
3298 // xinef: inform ai about spellhit
3300
3302
3304}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:305
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8620
void CallScriptOnHitHandlers()
Definition Spell.cpp:8633
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8646

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3307{
3308 uint32 effectMask = target->effectMask;
3309 if (!target->item || !effectMask)
3310 return;
3311
3314
3315 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3316 if (effectMask & (1 << effectNumber))
3317 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3318
3320
3322}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2523{
2524 if (!target || target->processed)
2525 return;
2526
2527 target->processed = true; // Target checked in apply effects procedure
2528
2529 // Get mask of effects for target
2530 uint8 mask = target->effectMask;
2531
2532 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2533 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2534 return;
2535
2536 if (!effectUnit || m_spellInfo->Id == 45927)
2537 {
2538 uint8 farMask = 0;
2539 // create far target mask
2540 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2541 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2542 if ((1 << i) & mask)
2543 farMask |= (1 << i);
2544
2545 if (!farMask)
2546 return;
2547 // find unit in world
2548 // Xinef: FindUnit Access without Map check!!! Intended
2549 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2550 if (!effectUnit)
2551 return;
2552
2553 // do far effects on the unit
2554 // can't use default call because of threading, do stuff as fast as possible
2555 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2556 if (farMask & (1 << i))
2557 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2558 return;
2559 }
2560
2561 if (effectUnit->IsAlive() != target->alive)
2562 return;
2563
2564 // Xinef: absorb delayed projectiles for 500ms
2566 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2567 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2568 )
2569 return; // No missinfo in that case
2570
2571 // Get original caster (if exist) and calculate damage/healing from him data
2573
2574 // Skip if m_originalCaster not avaiable
2575 if (!caster)
2576 return;
2577
2578 SpellMissInfo missInfo = target->missCondition;
2579
2580 // Need init unitTarget by default unit (can changed in code on reflect)
2581 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2582 unitTarget = effectUnit;
2583
2584 // Reset damage/healing counter
2585 m_damage = target->damage;
2586 m_healing = -target->damage;
2587
2588 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2589
2592
2593 //Spells with this flag cannot trigger if effect is casted on self
2595 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2596 Unit* reflectionSource = nullptr;
2597 Unit* spellHitTarget = nullptr;
2598
2599 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2600 spellHitTarget = unitTarget;
2601 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2602 {
2603 missInfo = target->reflectResult;
2604 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2605 {
2606 spellHitTarget = m_caster;
2608 reflectionSource = effectUnit;
2609 if (m_caster->IsCreature())
2611 }
2612 }
2613
2614 if (spellHitTarget)
2615 {
2616 if (reflectionSource)
2617 {
2618 m_reflectionTarget = reflectionSource;
2619 m_reflectionTargetGuid = reflectionSource->GetGUID();
2620 m_reflectionTargetPosition.Relocate(reflectionSource);
2621 }
2622 else
2623 {
2624 m_reflectionTarget = nullptr;
2627 }
2628
2629 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2630
2631 m_reflectionTarget = nullptr;
2634 if (missInfo2 != SPELL_MISS_NONE)
2635 {
2636 if (missInfo2 != SPELL_MISS_MISS)
2637 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2638 m_damage = 0;
2639 spellHitTarget = nullptr;
2640
2641 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2642 if (missInfo2 == SPELL_MISS_EVADE)
2643 missInfo = SPELL_MISS_EVADE;
2644 }
2645 }
2646
2647 // Do not take combo points on dodge and miss
2648 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2649 {
2650 m_needComboPoints = false;
2651 // Restore spell mods for a miss/dodge/parry Cold Blood
2653 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2654 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2655 }
2656
2657 // Fill base trigger info
2658 uint32 procAttacker = m_procAttacker;
2659 uint32 procVictim = m_procVictim;
2660 uint32 procEx = m_procEx;
2661
2662 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2663 if (canEffectTrigger && !procAttacker && !procVictim)
2664 {
2665 bool positive = true;
2666 if (m_damage > 0)
2667 positive = false;
2668 else if (!m_healing)
2669 {
2670 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2671 // If at least one effect negative spell is negative hit
2672 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2673 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2674 {
2675 positive = false;
2676 break;
2677 }
2678 }
2679 switch (m_spellInfo->DmgClass)
2680 {
2682 if (positive)
2683 {
2686 }
2687 else
2688 {
2691 }
2692 break;
2694 if (positive)
2695 {
2698 }
2699 else
2700 {
2703 }
2704 break;
2705 }
2706 }
2708
2709 // All calculated do it!
2710 // Do healing and triggers
2711 if (m_healing > 0)
2712 {
2713 bool crit = target->crit;
2714 uint32 addhealth = m_healing;
2715
2716 if (crit)
2717 {
2718 procEx |= PROC_EX_CRITICAL_HIT;
2719 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2720 }
2721 else
2722 procEx |= PROC_EX_NORMAL_HIT;
2723
2724 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2725
2726 // Xinef: override with forced crit, only visual result
2727 if (GetSpellValue()->ForcedCritResult)
2728 {
2729 crit = true;
2730 procEx |= PROC_EX_CRITICAL_HIT;
2731 }
2732
2733 int32 gain = caster->HealBySpell(healInfo, crit);
2734 float threat = float(gain) * 0.5f;
2735 if (caster->IsClass(CLASS_PALADIN))
2736 threat *= 0.5f;
2737
2739 m_healing = gain;
2740
2741 // Xinef: if heal acutally healed something, add no overheal flag
2742 if (m_healing)
2743 procEx |= PROC_EX_NO_OVERHEAL;
2744
2745 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2746 if (canEffectTrigger)
2747 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2748 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2749 }
2750 // Do damage and triggers
2751 else if (m_damage > 0)
2752 {
2754
2755 // Fill base damage struct (unitTarget - is real spell target)
2757
2758 // Add bonuses and fill damageInfo struct
2759 // Dancing Rune Weapon...
2760 if (m_caster->GetEntry() == 27893)
2761 {
2762 if (Unit* owner = m_caster->GetOwner())
2763 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2764 }
2765 else
2766 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2767
2768 // xinef: override miss info after absorb / block calculations
2769 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2770 {
2771 //if (damageInfo.absorb > 0)
2772 // missInfo = SPELL_MISS_ABSORB;
2773 if (damageInfo.blocked)
2774 missInfo = SPELL_MISS_BLOCK;
2775 }
2776
2777 // Xinef: override with forced crit, only visual result
2778 if (GetSpellValue()->ForcedCritResult)
2779 {
2780 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2781 }
2782
2783 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2784
2785 // xinef: health leech handling
2787 {
2788 uint8 effIndex = EFFECT_0;
2789 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2790 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2791 break;
2792
2793 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2794
2795 // get max possible damage, don't count overkill for heal
2796 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2797
2798 if (m_caster->IsAlive())
2799 {
2800 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2801 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2802
2803 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2804 m_caster->HealBySpell(healInfo);
2805 }
2806 }
2807
2808 // Send log damage message to client
2809 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2810 // Xinef: send info to target about reflect
2811 if (reflectedSpell)
2812 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2813
2814 procEx |= createProcExtendMask(&damageInfo, missInfo);
2815 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2816
2817 caster->DealSpellDamage(&damageInfo, true, this);
2818
2819 // do procs after damage, eg healing effects
2820 // no need to check if target is alive, done in procdamageandspell
2821
2822 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2823 if (canEffectTrigger)
2824 {
2825 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2826 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2827 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2828
2831 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2832 }
2833
2834 m_damage = damageInfo.damage;
2835 }
2836 // Passive spell hits/misses or active spells only misses (only triggers)
2837 else
2838 {
2839 // Fill base damage struct (unitTarget - is real spell target)
2841 procEx |= createProcExtendMask(&damageInfo, missInfo);
2842 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2843 if (canEffectTrigger)
2844 {
2845 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2846 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2847 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2848
2849 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2850 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2854 }
2855
2856 // Failed Pickpocket, reveal rogue
2858 {
2862 }
2863 }
2864
2865 if (m_caster)
2866 {
2868 {
2871
2872 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2873 if (effectUnit->IsInCombatWith(m_caster))
2874 {
2875 if (Creature* creature = effectUnit->ToCreature())
2876 {
2877 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2878 {
2879 creature->SetLootRecipient(m_caster);
2880 }
2881 }
2882 }
2883
2884 // Unsure if there are more spells that are not supposed to stop enemy from
2885 // regenerating HP from food, so for now it stays as an ID.
2886 const uint32 SPELL_PREMEDITATION = 14183;
2887 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2888 {
2889 if (!effectUnit->IsStandState())
2890 {
2892 }
2893 }
2894 }
2895 }
2896
2897 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2899 {
2900 m_caster->SetInCombatWith(effectUnit);
2901 }
2902
2903 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2905 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2906
2907 if (spellHitTarget)
2908 {
2909 //AI functions
2910 if (spellHitTarget->IsCreature())
2911 {
2912 if (spellHitTarget->ToCreature()->IsAIEnabled)
2913 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2914 }
2915
2917 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2918
2919 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2920 DoTriggersOnSpellHit(spellHitTarget, mask);
2921
2922 // if target is fallged for pvp also flag caster if a player
2923 // xinef: do not flag spells with aura bind sight (no special attribute)
2924 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2926 {
2927 m_caster->ToPlayer()->UpdatePvP(true);
2928 }
2929
2931 }
2932}
@ SPELL_EFFECT_HEALTH_LEECH
Definition SharedDefines.h:798
@ SPELL_ATTR1_NO_THREAT
Definition SharedDefines.h:440
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition SharedDefines.h:520
@ CLASS_PALADIN
Definition SharedDefines.h:142
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition SharedDefines.h:413
@ SPELL_HIT_TYPE_CRIT
Definition SharedDefines.h:1547
SpellMissInfo
Definition SharedDefines.h:1529
@ SPELL_MISS_DODGE
Definition SharedDefines.h:1533
@ SPELL_MISS_IMMUNE2
Definition SharedDefines.h:1538
@ SPELL_MISS_RESIST
Definition SharedDefines.h:1532
@ SPELL_MISS_MISS
Definition SharedDefines.h:1531
@ SPELL_MISS_BLOCK
Definition SharedDefines.h:1535
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition SharedDefines.h:564
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:53
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition SpellInfo.h:186
@ PROC_EX_NO_OVERHEAL
Definition SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:123
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition Spell.h:278
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:32
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition Unit.cpp:16010
@ NODAMAGE
Definition Unit.h:254
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:251
@ HEAL
Definition Unit.h:253
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition CreatureAI.h:148
virtual void SpellHit(Unit *, SpellInfo const *)
Definition CreatureAI.h:145
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition Creature.cpp:3737
CreatureAI * AI() const
Definition Creature.h:145
Definition Unit.h:332
Definition Unit.h:375
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition HostileRefMgr.cpp:35
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:9917
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7232
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1529
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:216
uint32 AttributesEx3
Definition SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition SpellInfo.cpp:1698
bool IsTargetingArea() const
Definition SpellInfo.cpp:1025
bool IsPositiveEffect(uint8 effIndex) const
Definition SpellInfo.cpp:1242
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:8724
SpellValue const * GetSpellValue()
Definition Spell.h:595
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:2934
Position m_reflectionTargetPosition
Definition Spell.h:671
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3200
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27
uint32 m_lastSanctuaryTime
Definition Unit.h:2048
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1470
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Unit.cpp:6545
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6378
bool CanProc()
Definition Unit.h:1516
bool IsPvP() const
Definition Unit.h:1022
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:12531
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition Unit.cpp:13663
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:11322
bool IsStandState() const
Definition Unit.cpp:16738
bool IsInCombatWith(Unit const *who) const
Definition Unit.cpp:20913
HostileRefMgr & getHostileRefMgr()
Definition Unit.h:940
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:14212
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:12400
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6410
bool IsAIEnabled
Definition Unit.h:2054
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:949
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:12649
void SetStandState(uint8 state)
Definition Unit.cpp:16753
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5250
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:814
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1327
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition Position.h:27
void Relocate(float x, float y)
Definition Position.h:77
Definition Unit.h:491

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), CLASS_PALADIN, ObjectGuid::Clear(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Unit::IsClass(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_reflectionTarget, m_reflectionTargetGuid, m_reflectionTargetPosition, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Position::Relocate(), Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1648{
1649 if (!unitTarget)
1650 return;
1651
1652 Player* player = unitTarget->ToPlayer();
1653 if (!player)
1654 {
1655 return;
1656 }
1657
1658 uint32 newitemid = itemId;
1659
1660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1661 if (!pProto)
1662 {
1663 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1664 return;
1665 }
1666
1667 uint32 addNumber = damage;
1668
1669 // bg reward have some special in code work
1670 bool SelfCast = true;
1671 switch (m_spellInfo->Id)
1672 {
1677 case SPELL_WS_MARK_TIE:
1680 SelfCast = true;
1681 break;
1683 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1684 addNumber = 3;
1685 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1686 addNumber = 2;
1687 else
1688 addNumber = 1;
1689 SelfCast = true;
1690 break;
1691 }
1692
1693 if (addNumber < 1)
1694 addNumber = 1;
1695 if (addNumber > pProto->GetMaxStackSize())
1696 addNumber = pProto->GetMaxStackSize();
1697
1698 /* == gem perfection handling == */
1699
1700 // the chance of getting a perfect result
1701 float perfectCreateChance = 0.0f;
1702
1703 // the resulting perfect item if successful
1704 uint32 perfectItemType = itemId;
1705
1706 // get perfection capability and chance
1707 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1708 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1709 newitemid = perfectItemType; // the perfect item replaces the regular one
1710
1711 /* == gem perfection handling over == */
1712
1713 /* == profession specialization handling == */
1714
1715 // init items_count to 1, since 1 item will be created regardless of specialization
1716 int32 itemsCount = 1;
1717 float additionalCreateChance = 0.0f;
1718 int32 additionalMaxNum = 0;
1719 // get the chance and maximum number for creating extra items
1720 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1721 {
1722 // roll with this chance till we roll not to create or we create the max num
1723 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1724 ++itemsCount;
1725 }
1726
1727 // really will be created more items
1728 addNumber *= itemsCount;
1729
1730 /* == profession specialization handling over == */
1731
1732 // can the player store the new item?
1733 ItemPosCountVec dest;
1734 uint32 no_space = 0;
1735 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1736 if (msg != EQUIP_ERR_OK)
1737 {
1738 // convert to possible store amount
1740 addNumber -= no_space;
1741 else
1742 {
1743 // if not created by another reason from full inventory or unique items amount limitation
1744 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1745 return;
1746 }
1747 }
1748
1749 if (addNumber)
1750 {
1751 // create the new item and store it
1752 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1753
1754 // was it successful? return error if not
1755 if (!pItem)
1756 {
1757 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1758 return;
1759 }
1760
1761 // set the "Crafted by ..." property of the item
1762 if (m_caster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1763 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1764
1765 // send info to the client
1766 player->SendNewItem(pItem, addNumber, true, SelfCast);
1767
1768 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
@ SPELL_WS_MARK_WINNER
Definition Battleground.h:97
@ SPELL_AV_MARK_LOSER
Definition Battleground.h:101
@ SPELL_WS_MARK_TIE
Definition Battleground.h:98
@ SPELL_WS_MARK_LOSER
Definition Battleground.h:96
@ SPELL_AB_MARK_LOSER
Definition Battleground.h:99
@ SPELL_WG_MARK_WINNER
Definition Battleground.h:105
@ SPELL_AB_MARK_WINNER
Definition Battleground.h:100
@ SPELL_AV_MARK_WINNER
Definition Battleground.h:102
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition SkillExtraItems.cpp:202
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:712
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:824
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4756
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition PlayerStorage.cpp:2530
bool HasSignature() const
Definition ItemTemplate.h:697

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, Object::IsPlayer(), ITEM_FIELD_CREATOR, m_caster, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2935{
2936 if (!unit || !effectMask)
2937 return SPELL_MISS_EVADE;
2938
2939 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
2940 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
2941 {
2942 return SPELL_MISS_IMMUNE;
2943 }
2944
2945 // disable effects to which unit is immune
2946 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
2947 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
2948 {
2949 if (effectMask & (1 << effectNumber))
2950 {
2951 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
2952 effectMask &= ~(1 << effectNumber);
2953 // Xinef: Buggs out polymorph
2954 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
2955 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
2956 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
2957 {
2958 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2959 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
2960
2961 if (debuff_resist_chance > 0)
2962 if (irand(0,10000) <= (debuff_resist_chance * 100))
2963 {
2964 effectMask &= ~(1 << effectNumber);
2965 returnVal = SPELL_MISS_RESIST;
2966 }
2967 }*/
2968 }
2969 }
2970 if (!effectMask)
2971 return returnVal;
2972
2973 if (unit->IsPlayer())
2974 {
2978 }
2979
2980 if (m_caster->IsPlayer())
2981 {
2984 }
2985
2986 if (m_caster != unit)
2987 {
2988 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
2989 // Xinef: Also check evade state
2990 if (m_spellInfo->Speed > 0.0f)
2991 {
2992 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
2993 return SPELL_MISS_EVADE;
2994
2996 return SPELL_MISS_EVADE;
2997 }
2998
2999 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3000 {
3002 }
3003 else if (m_caster->IsFriendlyTo(unit))
3004 {
3005 // for delayed spells ignore negative spells (after duel end) for friendly targets
3007 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3008 return SPELL_MISS_EVADE;
3009
3010 // assisting case, healing and resurrection
3012 {
3015 m_caster->ToPlayer()->UpdatePvP(true);
3016 }
3017
3018 // xinef: triggered spells should not prolong combat
3020 {
3021 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3022 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3023 }
3024 }
3025 }
3026
3027 uint8 aura_effmask = 0;
3028 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3029 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3030 aura_effmask |= 1 << i;
3031
3032 Unit* originalCaster = GetOriginalCaster();
3033 if (!originalCaster)
3034 originalCaster = m_caster;
3035
3036 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3037 // Xinef: Do not increase diminishing level for self cast
3039 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3040 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3041 {
3044
3045 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3046
3047 // Increase Diminishing on unit, current informations for actually casts will use values above
3048 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3050 {
3051 // Do not apply diminish return if caster is NPC
3053 {
3055 }
3056 }
3057 }
3058
3060 {
3062 }
3063
3064 if (aura_effmask)
3065 {
3066 // Select rank for aura with level requirements only in specific cases
3067 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3068 SpellInfo const* aurSpellInfo = m_spellInfo;
3069 int32 basePoints[3];
3070 if (scaleAura)
3071 {
3073 ASSERT(aurSpellInfo);
3074 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3075 {
3076 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3077 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3078 {
3079 aurSpellInfo = m_spellInfo;
3080 break;
3081 }
3082 }
3083 }
3084
3085 if (m_originalCaster)
3086 {
3087 bool refresh = false;
3089 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3090 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3091
3092 // xinef: if aura was not refreshed, add proc ex
3093 if (!refresh)
3095
3096 if (m_spellAura)
3097 {
3098 // Prevent aura application if target is banished and immuned
3101 {
3103 return SPELL_MISS_IMMUNE;
3104 }
3105
3106 // Set aura stack amount to desired value
3108 {
3109 if (!refresh)
3111 else
3113 }
3114
3115 // Now Reduce spell duration using data received at spell hit
3116 int32 duration = m_spellAura->GetMaxDuration();
3117 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3118
3119 // Xinef: if unit == caster - test versus original unit if available
3120 float diminishMod = 1.0f;
3121 if (unit == m_caster && m_targets.GetUnitTarget())
3123 else
3124 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3125
3126 // unit is immune to aura if it was diminished to 0 duration
3127 if (diminishMod == 0.0f)
3128 {
3131 return SPELL_MISS_IMMUNE;
3132 bool found = false;
3133 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3134 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3135 found = true;
3136 if (!found)
3137 return SPELL_MISS_IMMUNE;
3138 }
3139 else
3140 {
3141 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3142
3143 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3145 positive = aurApp->IsPositive();
3146
3147 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3148
3149 // xinef: haste affects duration of those spells twice
3152
3153 if (m_spellValue->AuraDuration != 0)
3154 {
3155 if (m_spellAura->GetMaxDuration() != -1)
3156 {
3158 }
3159
3161 }
3162 else if (duration != m_spellAura->GetMaxDuration())
3163 {
3164 m_spellAura->SetMaxDuration(duration);
3165 m_spellAura->SetDuration(duration);
3166 }
3167
3168 // xinef: apply relic cooldown, imo best place to add this
3171
3174 }
3175 }
3176 }
3177 }
3178
3179 int8 sanct_effect = -1;
3180
3181 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3182 {
3183 // handle sanctuary effects after aura apply!
3184 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3185 {
3186 sanct_effect = effectNumber;
3187 continue;
3188 }
3189
3190 if (effectMask & (1 << effectNumber))
3191 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3192 }
3193
3194 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3195 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3196
3197 return SPELL_MISS_NONE;
3198}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:65
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition SharedDefines.h:3526
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:868
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:591
DiminishingReturnsType
Definition SharedDefines.h:3499
@ DRTYPE_PLAYER
Definition SharedDefines.h:3501
@ DRTYPE_ALL
Definition SharedDefines.h:3502
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition SpellMgr.cpp:275
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:58
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:245
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:214
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:184
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:183
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:255
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
Definition SpellAuras.h:37
int32 GetMaxDuration() const
Definition SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2747
void _RegisterForTargets()
Definition SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
bool isWorldBoss() const
Definition Creature.h:125
bool IsInEvadeMode() const
Definition Creature.h:139
float GetFloatValue(uint16 index) const
Definition Object.cpp:306
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2538
Unit * GetOriginalCaster() const
Definition Spell.h:586
Definition SpellAuras.h:279
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5830
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:15037
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:15063
uint32 GetCombatTimer() const
Definition Unit.h:927
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12912
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:17275
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:732
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:15077
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:14903
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1304
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition Unit.cpp:13821
bool HasReflectSpellsAura() const
Definition Unit.h:1771
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1276
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12827
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:12996
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:12981
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:10288
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:13966
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1262
uint32 flags_extra
Definition CreatureData.h:246
int32 AuraDuration
Definition Spell.h:227
uint8 AuraStackAmount
Definition Spell.h:226

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), Unit::HasReflectSpellsAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3201{
3202 // Apply additional spell effects to target
3204 if (m_preCastSpell)
3205 {
3206 // Paladin immunity shields
3207 if (m_preCastSpell == 61988)
3208 {
3209 // Cast Forbearance
3210 m_caster->CastSpell(unit, 25771, true);
3211 // Cast Avenging Wrath Marker
3212 unit->CastSpell(unit, 61987, true);
3213 }
3214
3215 // Avenging Wrath
3216 if (m_preCastSpell == 61987)
3217 // Cast the serverside immunity shield marker
3218 m_caster->CastSpell(unit, 61988, true);
3219
3220 // Fearie Fire (Feral) - damage
3221 if (m_preCastSpell == 60089)
3222 m_caster->CastSpell(unit, m_preCastSpell, true);
3223 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3224 // Blizz seems to just apply aura without bothering to cast
3226 }
3227
3228 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3229 // this is executed after spell proc spells on target hit
3230 // spells are triggered for each hit spell target
3231 // info confirmed with retail sniffs of permafrost and shadow weaving
3232 if (!m_hitTriggerSpells.empty())
3233 {
3234 int _duration = 0;
3235 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3236 {
3237 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3238 {
3239 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3240 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3241
3242 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3243 // set duration of current aura to the triggered spell
3244 if (i->triggeredSpell->GetDuration() == -1)
3245 {
3246 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3247 {
3248 // get duration from aura-only once
3249 if (!_duration)
3250 {
3251 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3252 _duration = aur ? aur->GetDuration() : -1;
3253 }
3254 triggeredAur->SetDuration(_duration);
3255 }
3256 }
3257 }
3258 }
3259 }
3260
3261 // trigger linked auras remove/apply
3263 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3264 {
3265 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3266 if (*i < 0)
3267 {
3268 unit->RemoveAurasDueToSpell(-(*i));
3269 }
3270 else
3271 {
3272 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3273 }
3274 }
3275}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:97
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:769
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5650
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:18893

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4252{
4254 return;
4255
4256 if (!gameObjTarget)
4257 return;
4258
4259 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4260 switch (action)
4261 {
4267 break;
4268 case GameObjectActions::Disturb: // What's the difference with Open?
4270 if (Unit* unitCaster = m_caster->ToUnit())
4271 gameObjTarget->Use(unitCaster);
4272 break;
4274 if (Unit* unitCaster = m_caster->ToUnit())
4275 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4276 [[fallthrough]];
4280 break;
4284 break;
4287 break;
4291 break;
4295 break;
4297 if (Unit* unitCaster = m_caster->ToUnit())
4298 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4299 break;
4304 {
4305 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4306
4307 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4308
4309 uint32 artKitValue = 0;
4310 if (templateAddon)
4311 artKitValue = templateAddon->artKits[artKitIndex];
4312
4313 if (artKitValue == 0)
4314 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4315 else
4316 gameObjTarget->SetGoArtKit(artKitValue);
4317
4318 break;
4319 }
4321 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4322 break;
4323 default:
4324 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4325 break;
4326 }
4327}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:154
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1618
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1615
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1410
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1424
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2142
void ResetDoorOrButton()
Definition GameObject.cpp:1400
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:932
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:911
void Use(Unit *user)
Definition GameObject.cpp:1460
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:834
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:888
Definition GameObjectData.h:666
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672

References AnimateCustom0, AnimateCustom1, AnimateCustom2, AnimateCustom3, Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, Close, CloseAndLock, Despawn, GameObject::DespawnOrUnsummon(), Destroy, Disturb, effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, Lock, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, MakeActive, MakeInert, None, Open, OpenAndUnlock, Rebuild, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), Unlock, GameObject::Use(), UseArtKit0, UseArtKit1, UseArtKit2, UseArtKit3, and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5787{
5789 return;
5790
5791 if (!m_caster->IsPlayer())
5792 return;
5793
5794 Player* player = m_caster->ToPlayer();
5795
5797 return;
5798
5799 // needed later
5801
5802 uint32 count = damage;
5803 if (count == 0) count = 1;
5804 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5805 {
5806 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5807 {
5808 if (m_spellInfo->Id == 45529)
5809 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5810 continue;
5811 player->SetRuneCooldown(j, 0);
5812 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5813 --count;
5814 }
5815 }
5816
5817 // Blood Tap
5818 if (m_spellInfo->Id == 45529 && count > 0)
5819 {
5820 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5821 {
5822 // Check if both runes are on cd as that is the only time when this needs to come into effect
5823 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5824 {
5825 // Should always update the rune with the lowest cd
5826 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5827 l++;
5828 player->SetRuneCooldown(l, 0);
5829 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5830 --count;
5831 }
5832 else
5833 break;
5834 }
5835 }
5836
5837 // Empower rune weapon
5838 if (m_spellInfo->Id == 47568)
5839 {
5840 // Need to do this just once
5841 if (effIndex != 0)
5842 return;
5843
5844 for (uint32 i = 0; i < MAX_RUNES; ++i)
5845 {
5846 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5847 {
5848 player->SetRuneCooldown(i, 0);
5849 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5850 }
5851 }
5852 }
5853
5854 // is needed to push through to the client that the rune is active
5855 //player->ResyncRunes(MAX_RUNES);
5856 m_caster->CastSpell(m_caster, 47804, true);
5857}
@ RUNE_FROST
Definition Player.h:407
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2518
uint8 GetRunesState() const
Definition Player.h:2507
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2519
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2508

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6162{
6164 return;
6165
6166 if (!unitTarget)
6167 return;
6168
6169 if (Player* player = unitTarget->ToPlayer())
6170 {
6171 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6172 }
6173}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4089{
4091 {
4092 return;
4093 }
4094
4095 if (!unitTarget || damage <= 0)
4096 {
4097 return;
4098 }
4099
4101}
void AddComboPointGain(Unit *target, int8 amount)
Definition Spell.h:541

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4671{
4673 {
4674 return;
4675 }
4676
4677 if (!unitTarget || !unitTarget->IsAlive())
4678 {
4679 return;
4680 }
4681
4683
4685}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5075
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2805

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2725{
2727 return;
2728
2729 if (!m_caster->IsPlayer())
2730 return;
2731
2732 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2733 int32 duration = m_spellInfo->GetDuration();
2734 // Caster not in world, might be spell triggered from aura removal
2735 if (!m_caster->IsInWorld())
2736 return;
2737
2738 // Remove old farsight if exist
2739 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2740
2741 DynamicObject* dynObj = new DynamicObject();
2743 {
2744 delete dynObj;
2745 return;
2746 }
2747
2748 dynObj->SetDuration(duration);
2749 dynObj->SetCasterViewpoint(updateViewerVisibility);
2750}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition DynamicObject.cpp:198
void SetCasterViewpoint(bool updateViewerVisibility)
Definition DynamicObject.cpp:226
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:480
int32 GetDuration() const
Definition SpellInfo.cpp:2350

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, DynamicObject, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2795{
2797 return;
2798
2799 if (!unitTarget->IsPlayer())
2800 return;
2801
2802 // not scale value for item based reward (/10 value expected)
2803 if (m_CastItem)
2804 {
2805 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2806 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2808 return;
2809 }
2810
2811 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2812 if (damage <= 50)
2813 {
2815 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2816 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2817 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2818 }
2819 else
2820 {
2821 //maybe we have correct honor_gain in damage already
2822 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2823 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2825 }
2826}
std::string ToString() const
Definition ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6068
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:38

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
WorldObject * GetOwner() const
Definition SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4330{
4332 return;
4333
4335 return;
4336
4337 Player* player = m_caster->ToPlayer();
4338
4339 // glyph sockets level requirement
4340 uint8 minLevel = 0;
4341 switch (m_glyphIndex)
4342 {
4343 case 0:
4344 case 1:
4345 minLevel = 15;
4346 break;
4347 case 2:
4348 minLevel = 50;
4349 break;
4350 case 3:
4351 minLevel = 30;
4352 break;
4353 case 4:
4354 minLevel = 70;
4355 break;
4356 case 5:
4357 minLevel = 80;
4358 break;
4359 }
4360 if (minLevel && m_caster->GetLevel() < minLevel)
4361 {
4363 return;
4364 }
4365
4366 // apply new one
4367 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4368 {
4369 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4370 {
4371 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4372 {
4373 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4374 {
4376 return; // glyph slot mismatch
4377 }
4378 }
4379
4380 // remove old glyph aura
4381 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4382 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4383 {
4384 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4385
4386 // Removed any triggered auras
4387 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4388 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4389 {
4390 Aura* aura = iter->second;
4391 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4392 {
4393 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4394 {
4395 player->RemoveOwnedAura(iter);
4396 continue;
4397 }
4398 }
4399 ++iter;
4400 }
4401
4402 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4403 }
4404
4405 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4407 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4408 player->SendTalentsInfoData(false);
4409 }
4410 }
4411}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition SharedDefines.h:687
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition SharedDefines.h:1137
@ SPELL_FAILED_INVALID_GLYPH
Definition SharedDefines.h:1135
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition SpellDefines.h:150
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2761
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14490
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3034
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1762
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1753
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1754
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4774
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:655
AuraMap & GetOwnedAuras()
Definition Unit.h:1336
bool PlayerLoading() const
Definition WorldSession.h:381
Definition DBCStructure.h:1030

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6295{
6297 return;
6298
6299 if (!unitTarget)
6300 return;
6301
6302 Player* player = unitTarget->ToPlayer();
6303 if (!player)
6304 {
6305 return;
6306 }
6307
6308 WorldLocation homeLoc;
6309 uint32 areaId = player->GetAreaId();
6310
6311 if (m_spellInfo->Effects[effIndex].MiscValue)
6312 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6313
6314 if (m_targets.HasDst())
6315 homeLoc.WorldRelocate(*destTarget);
6316 else
6317 {
6318 homeLoc = player->GetWorldLocation();
6319 }
6320
6321 player->SetHomebind(homeLoc, areaId);
6322
6323 // binding
6324 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6325 data << float(homeLoc.GetPositionX());
6326 data << float(homeLoc.GetPositionY());
6327 data << float(homeLoc.GetPositionZ());
6328 data << uint32(homeLoc.GetMapId());
6329 data << uint32(areaId);
6330 player->SendDirectMessage(&data);
6331
6332 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6333 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6334 // zone update
6335 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6336 data << m_caster->GetGUID();
6337 data << uint32(areaId);
6338 player->SendDirectMessage(&data);
6339}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5689
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4902
Definition Position.h:256
void WorldRelocate(const WorldLocation &loc)
Definition Position.h:264
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition Position.h:286
@ SMSG_BINDPOINTUPDATE
Definition Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition Opcodes.h:374

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4697{
4699 return;
4700
4701 if (m_caster->IsPlayer())
4702 m_caster->ToPlayer()->SetCanBlock(true);
4703}
void SetCanBlock(bool value)
Definition Player.cpp:13131

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6222{
6224 return;
6225
6226 if (!m_caster->IsPlayer())
6227 return;
6228
6229 Player* p_caster = m_caster->ToPlayer();
6230 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6231 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6232
6233 for (; n_buttons; --n_buttons, ++button_id)
6234 {
6235 ActionButton const* ab = p_caster->GetActionButton(button_id);
6236 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6237 continue;
6238
6241 uint32 spell_id = ab->GetAction();
6242 if (!spell_id)
6243 continue;
6244
6245 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6246 if (!spellInfo)
6247 continue;
6248
6249 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6250 continue;
6251
6253 continue;
6254
6255 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6256 if (m_caster->GetPower(POWER_MANA) < cost)
6257 continue;
6258
6260 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6261 }
6262}
@ ACTION_BUTTON_SPELL
Definition Player.h:231
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition SharedDefines.h:657
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:5648
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3893
Definition Player.h:249
uint32 GetAction() const
Definition Player.h:257
ActionButtonType GetType() const
Definition Player.h:256

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4916{
4918 {
4919 if (!unitTarget)
4920 return;
4921
4922 ObjectGuid targetGUID = ObjectGuid::Empty;
4923 Player* player = m_caster->ToPlayer();
4924 if (player)
4925 {
4926 // charge changes fall time
4928
4930 {
4931 targetGUID = unitTarget->GetGUID();
4932 }
4933 }
4934
4935 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4936 // Spell is not using explicit target - no generated path
4937 if (!m_preGeneratedPath)
4938 {
4940 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4941 }
4942 else
4943 {
4944 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4945 }
4946
4947 if (player)
4948 {
4949 sScriptMgr->AnticheatSetUnderACKmount(player);
4950 }
4951 }
4952}
#define SPEED_CHARGE
Definition MotionMaster.h:124
@ EVENT_CHARGE
Definition SharedDefines.h:3577
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:719
static ObjectGuid const Empty
Definition ObjectGuid.h:120
void SetFallInformation(uint32 time, float z)
Definition Player.h:2338
MotionMaster * GetMotionMaster()
Definition Unit.h:1713
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2839
float m_positionZ
Definition Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition Position.h:201
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1777{
1779 return;
1780
1781 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1782 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1783}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5103
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1647

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1786{
1788 return;
1789
1790 if (!unitTarget)
1791 return;
1792
1793 Player* player = unitTarget->ToPlayer();
1794 if (!player)
1795 {
1796 return;
1797 }
1798
1799 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1800
1801 if (itemId)
1802 DoCreateItem(effIndex, itemId);
1803
1804 // special case: fake item replaced by generate using spell_loot_template
1806 {
1807 if (itemId)
1808 {
1809 if (!player->HasItemCount(itemId))
1810 return;
1811
1812 // remove reagent
1813 uint32 count = 1;
1814 player->DestroyItemCount(itemId, count, true);
1815
1816 // create some random items
1818 }
1819 else
1820 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1821 }
1823}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:13486
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3120
bool IsLootCrafting() const
Definition SpellInfo.cpp:925

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1826{
1828 return;
1829
1830 if (!unitTarget)
1831 return;
1832
1833 Player* player = unitTarget->ToPlayer();
1834 if (!player)
1835 {
1836 return;
1837 }
1838
1839 // create some random items
1842}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5860{
5862 return;
5863
5865 return;
5866
5867 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5868 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5869 if (!pet)
5870 return;
5871
5872 // add to world
5873 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5874
5875 // unitTarget has pet now
5876 unitTarget->SetMinion(pet, true);
5877
5878 pet->InitTalentForLevel();
5879
5880 if (unitTarget->IsPlayer())
5881 {
5884 }
5885}
@ CLASS_HUNTER
Definition SharedDefines.h:143
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:305
void InitTalentForLevel()
Definition Pet.cpp:2228
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9514
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:10762
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:17378

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5267{
5269 return;
5270
5271 int32 mana = 0;
5272 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5273 {
5274 if (!m_caster->m_SummonSlot[slot])
5275 continue;
5276
5278 if (totem && totem->IsTotem())
5279 {
5280 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5281 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5282 if (spellInfo)
5283 {
5284 mana += spellInfo->ManaCost;
5286 }
5287 totem->ToTotem()->UnSummon();
5288 }
5289 }
5290 ApplyPct(mana, damage);
5291 if (mana)
5292 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5293}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3572
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3562
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:73
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2357
uint32 ManaCostPercentage
Definition SpellInfo.h:367
uint32 ManaCost
Definition SpellInfo.h:363
void UnSummon(Milliseconds msTime=0ms) override
Definition Totem.cpp:122
Totem * ToTotem()
Definition Unit.h:715
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition Unit.cpp:1251
uint32 GetCreateMana() const
Definition Unit.h:1111
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2036

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM_FIRE, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5888{
5890 return;
5891
5892 if (!unitTarget)
5893 return;
5894
5895 Player* player = unitTarget->ToPlayer();
5896 if (!player)
5897 {
5898 return;
5899 }
5900
5901 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5902 if (sTaxiNodesStore.LookupEntry(nodeid))
5903 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5904}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4467{
4469 return;
4470
4472 return;
4473
4474 if (Player* caster = m_caster->ToPlayer())
4475 {
4476 caster->UpdateCraftSkill(m_spellInfo->Id);
4477 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4478 }
4479
4480 // item will be removed at disenchanting end
4481}
@ LOOT_DISENCHANTING
Definition LootMgr.h:83

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4553{
4555 return;
4556
4557 if (!unitTarget || !unitTarget->IsPet())
4558 return;
4559
4560 Pet* pet = unitTarget->ToPet();
4561
4562 ExecuteLogEffectUnsummonObject(effIndex, pet);
4564}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:881
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5121

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2574{
2576 return;
2577
2578 if (!unitTarget)
2579 return;
2580
2581 // Create dispel mask by dispel type
2582 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2583 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2584
2585 DispelChargesList dispel_list;
2586 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2587 if (dispel_list.empty())
2588 return;
2589
2590 // Ok if exist some buffs for dispel try dispel it
2591 uint32 failCount = 0;
2592 DispelChargesList success_list;
2593 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2594 // dispel N = damage buffs (or while exist buffs for dispel)
2595 for (int32 count = 0; count < damage && !dispel_list.empty();)
2596 {
2597 // Random select buff for dispel
2598 DispelChargesList::iterator itr = dispel_list.begin();
2599 std::advance(itr, urand(0, dispel_list.size() - 1));
2600
2601 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2602 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2603 if (!chance)
2604 {
2605 dispel_list.erase(itr);
2606 continue;
2607 }
2608 else
2609 {
2610 if (roll_chance_i(chance))
2611 {
2612 bool alreadyListed = false;
2613 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2614 {
2615 if (successItr->first->GetId() == itr->first->GetId())
2616 {
2617 ++successItr->second;
2618 alreadyListed = true;
2619 }
2620 }
2621 if (!alreadyListed)
2622 success_list.push_back(std::make_pair(itr->first, 1));
2623 --itr->second;
2624 if (itr->second <= 0)
2625 dispel_list.erase(itr);
2626 }
2627 else
2628 {
2629 if (!failCount)
2630 {
2631 // Failed to dispell
2632 dataFail << m_caster->GetGUID(); // Caster GUID
2633 dataFail << unitTarget->GetGUID(); // Victim GUID
2634 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2635 }
2636 ++failCount;
2637 dataFail << uint32(itr->first->GetId()); // Spell Id
2638 }
2639 ++count;
2640 }
2641 }
2642
2643 if (failCount)
2644 m_caster->SendMessageToSet(&dataFail, true);
2645
2646 // put in combat
2649
2650 if (success_list.empty())
2651 return;
2652
2653 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2654 // Send packet header
2655 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2656 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2657 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2658 dataSuccess << uint8(0); // not used
2659 dataSuccess << uint32(success_list.size()); // count
2660 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2661 {
2662 // Send dispelled spell info
2663 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2664 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2665 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2666 }
2667 m_caster->SendMessageToSet(&dataSuccess, true);
2668
2669 // On success dispel
2670 // Devour Magic
2672 {
2673 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2674 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2675 // Glyph of Felhunter
2676 if (Unit* owner = m_caster->GetOwner())
2677 if (owner->GetAura(56249))
2678 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2679 }
2680}
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition SharedDefines.h:3799
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition SpellMgr.h:40
uint32 GetCategory() const
Definition SpellInfo.cpp:871
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:5011
@ SMSG_DISPEL_FAILED
Definition Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition Opcodes.h:665

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5172{
5174 return;
5175
5176 if (!unitTarget)
5177 return;
5178
5179 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5180
5181 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5182
5183 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5184 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5185 {
5186 Aura* aura = itr->second;
5188 continue;
5190 {
5191 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5192 {
5193 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5194
5195 // spell only removes 1 bleed effect do not continue
5196 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5197 {
5198 break;
5199 }
5200 }
5201 }
5202 }
5203
5204 for (; dispel_list.size(); dispel_list.pop())
5205 {
5206 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5207 }
5208
5209 // put in combat
5212}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:105
uint32 GetId() const
Definition SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition SpellAuras.cpp:1182
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4845

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2697{
2699 return;
2700
2701 // Check for possible target
2702 if (!unitTarget || unitTarget->IsEngaged())
2703 return;
2704
2705 // target must be OK to do this
2707 return;
2708
2711}
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_FLEEING
Definition UnitDefines.h:177
@ UNIT_STATE_STUNNED
Definition UnitDefines.h:173
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition MotionMaster.cpp:847
void SetFacingTo(float ori)
Definition Unit.cpp:20279
bool IsEngaged() const
Definition Unit.h:914
float GetAngle(const Position *pos) const
Definition Position.cpp:85

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2683{
2685 return;
2686
2688}
virtual void SetCanDualWield(bool value)
Definition Unit.h:957

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4104{
4106 return;
4107
4108 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4109 return;
4110
4111 Player* caster = m_caster->ToPlayer();
4112 Player* target = unitTarget->ToPlayer();
4113
4114 // caster or target already have requested duel
4115 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4116 return;
4117
4118 // Players can only fight a duel in zones with this flag
4119 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4120 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4121 {
4122 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4123 return;
4124 }
4125
4126 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4127 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4128 {
4129 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4130 return;
4131 }
4132
4133 //CREATE DUEL FLAG OBJECT
4134 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4135 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4136
4137 Map* map = m_caster->GetMap();
4138 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4139 map, m_caster->GetPhaseMask(),
4143 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4144 {
4145 delete pGameObj;
4146 return;
4147 }
4148
4151 int32 duration = m_spellInfo->GetDuration();
4152 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4153 pGameObj->SetSpellId(m_spellInfo->Id);
4154
4155 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4156
4157 m_caster->AddGameObject(pGameObj);
4158 map->AddToMap(pGameObj, true);
4159 //END
4160
4161 // Send request
4162 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4163 data << pGameObj->GetGUID();
4164 data << caster->GetGUID();
4165 caster->SendDirectMessage(&data);
4166 target->SendDirectMessage(&data);
4167
4168 // create duel-info
4169 bool isMounted = (GetSpellInfo()->Id == 62875);
4170 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4171 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4172
4173 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4174 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4175
4176 sScriptMgr->OnPlayerDuelRequest(target, caster);
4177}
@ AREA_FLAG_ALLOW_DUELS
Definition DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition SharedDefines.h:1039
@ PLAYER_DUEL_ARBITER
Definition UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition UpdateFields.h:402
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition GameObject.cpp:1284
void SetSpellId(uint32 id)
Definition GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:639
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:193
PlayerSocial * GetSocial()
Definition Player.h:1143
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5115
Definition Transport.h:115
uint32 GetFaction() const
Definition Unit.h:834
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6279
uint32 GetPhaseMask() const
Definition Object.h:513
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:389
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GameObject, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), Player::SendDirectMessage(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:50
@ SPELLFAMILY_GENERIC
Definition SharedDefines.h:3794
@ SPELLFAMILY_PALADIN
Definition SharedDefines.h:3804
@ SPELLFAMILY_ROGUE
Definition SharedDefines.h:3802
@ UNIT_FIELD_MOUNTDISPLAYID
Definition UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition GameObject.h:208
time_t GetRespawnTime() const
Definition GameObject.h:183
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition MapScripts.cpp:31
Definition SpellMgr.h:470
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:17324
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:652
AttackerSet const & getAttackers() const
Definition Unit.h:883
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition Object.cpp:2359

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5296{
5298 return;
5299
5300 if (!unitTarget)
5301 return;
5302
5303 Player* player = unitTarget->ToPlayer();
5304 if (!player)
5305 {
5306 return;
5307 }
5308
5309 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5310
5311 // -1 means all player equipped items and -2 all items
5312 if (slot < 0)
5313 {
5314 player->DurabilityPointsLossAll(damage, (slot < -1));
5316 return;
5317 }
5318
5319 // invalid slot value
5320 if (slot >= INVENTORY_SLOT_BAG_END)
5321 return;
5322
5323 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5324 {
5325 player->DurabilityPointsLoss(item, damage);
5326 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5327 }
5328}
@ INVENTORY_SLOT_BAG_END
Definition Player.h:695
#define INVENTORY_SLOT_BAG_0
Definition Player.h:665
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:442
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4758
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4784
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5089

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5331{
5333 return;
5334
5335 if (!unitTarget)
5336 return;
5337
5338 Player* player = unitTarget->ToPlayer();
5339 if (!player)
5340 {
5341 return;
5342 }
5343
5344 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5345
5346 // FIXME: some spells effects have value -1/-2
5347 // Possibly its mean -1 all player equipped items and -2 all items
5348 if (slot < 0)
5349 {
5350 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5351 return;
5352 }
5353
5354 // invalid slot value
5355 if (slot >= INVENTORY_SLOT_BAG_END)
5356 return;
5357
5358 if (damage <= 0)
5359 return;
5360
5361 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5362 player->DurabilityLoss(item, float(damage) / 100.0f);
5363}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4714
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4740

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4414{
4416 return;
4417
4418 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4419 if (!unitTarget)
4420 return;
4421
4422 Player* item_owner = unitTarget->ToPlayer();
4423 if (!item_owner)
4424 {
4425 return;
4426 }
4427
4429 if (!item)
4430 return;
4431
4432 // must be equipped
4433 if (!item->IsEquipped())
4434 return;
4435
4436 if (m_spellInfo->Effects[effIndex].MiscValue)
4437 {
4438 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4439 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4440 if (!duration)
4441 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4442 if (!duration)
4443 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4444
4445 // Xinef: Venomhide poison, no other spell uses this effect...
4446 if (m_spellInfo->Id == 14792)
4447 duration = 5 * MINUTE * IN_MILLISECONDS;
4448
4449 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4450 if (!pEnchant)
4451 return;
4452
4453 // Always go to temp enchantment slot
4455
4456 // Enchantment will not be applied if a different one already exists
4457 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4458 return;
4459
4460 // Apply the temporary enchantment
4461 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4462 item_owner->ApplyEnchantment(item, slot, true);
4463 }
4464}
EnchantmentSlot
Definition Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:685
bool IsEquipped() const
Definition Item.cpp:789
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:920
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition PlayerStorage.cpp:4303
uint32 charges
Definition DBCStructure.h:1844

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2841{
2843 return;
2844
2845 if (!m_caster->IsPlayer())
2846 return;
2847 if (!itemTarget)
2848 return;
2849
2850 Player* p_caster = m_caster->ToPlayer();
2851
2852 // Handle vellums
2854 {
2855 // destroy one vellum from stack
2856 uint32 count = 1;
2857 p_caster->DestroyItemCount(itemTarget, count, true);
2858 unitTarget = p_caster;
2859 // and add a scroll
2860 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2861 itemTarget = nullptr;
2862 m_targets.SetItemTarget(nullptr);
2863 }
2864 else
2865 {
2866 // do not increase skill if vellum used
2868 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2869
2870 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2871 if (!enchant_id)
2872 return;
2873
2874 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2875 if (!pEnchant)
2876 return;
2877
2878 // item can be in trade slot and have owner diff. from caster
2879 Player* item_owner = itemTarget->GetOwner();
2880 if (!item_owner)
2881 return;
2882
2883 // remove old enchanting before applying new if equipped
2885
2887
2888 // add new enchanting if equipped
2890
2891 item_owner->RemoveTradeableItem(itemTarget);
2893 }
2894}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition PlayerStorage.cpp:4138
void SetItemTarget(Item *item)
Definition Spell.cpp:328

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2897{
2899 return;
2900
2901 if (!m_caster->IsPlayer())
2902 return;
2903 if (!itemTarget)
2904 return;
2905
2906 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2907 if (!enchant_id)
2908 return;
2909
2910 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2911 if (!pEnchant)
2912 return;
2913
2914 // support only enchantings with add socket in this slot
2915 {
2916 bool add_socket = false;
2917 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2918 {
2919 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2920 {
2921 add_socket = true;
2922 break;
2923 }
2924 }
2925 if (!add_socket)
2926 {
2927 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2929 return;
2930 }
2931 }
2932
2933 // item can be in trade slot and have owner diff. from caster
2934 Player* item_owner = itemTarget->GetOwner();
2935 if (!item_owner)
2936 return;
2937
2938 // remove old enchanting before applying new if equipped
2940
2942
2943 // add new enchanting if equipped
2945
2946 item_owner->RemoveTradeableItem(itemTarget);
2948}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2951{
2953 return;
2954
2955 if (!m_caster->IsPlayer())
2956 return;
2957
2958 Player* p_caster = m_caster->ToPlayer();
2959
2960 // Rockbiter Weapon apply to both weapon
2961 if (!itemTarget)
2962 return;
2964 {
2965 uint32 spell_id = 0;
2966
2967 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2968 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2969 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2970 switch (damage)
2971 {
2972 // Rank 1
2973 case 2:
2974 spell_id = 36744;
2975 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2976 // Rank 2
2977 case 4:
2978 spell_id = 36753;
2979 break; // 0% [ 7% == 4, 14% == 4]
2980 case 5:
2981 spell_id = 36751;
2982 break; // 20%
2983 // Rank 3
2984 case 6:
2985 spell_id = 36754;
2986 break; // 0% [ 7% == 6, 14% == 6]
2987 case 7:
2988 spell_id = 36755;
2989 break; // 20%
2990 // Rank 4
2991 case 9:
2992 spell_id = 36761;
2993 break; // 0% [ 7% == 6]
2994 case 10:
2995 spell_id = 36758;
2996 break; // 14%
2997 case 11:
2998 spell_id = 36760;
2999 break; // 20%
3000 default:
3001 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
3002 return;
3003 }
3004
3005 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3006 if (!spellInfo)
3007 {
3008 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3009 return;
3010 }
3011
3012 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3013 {
3014 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3015 {
3016 if (item->IsFitToSpellRequirements(m_spellInfo))
3017 {
3018 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3019 SpellCastTargets targets;
3020 targets.SetItemTarget(item);
3021 spell->prepare(&targets);
3022 }
3023 }
3024 }
3025 return;
3026 }
3027 if (!itemTarget)
3028 return;
3029
3030 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3031
3032 if (!enchant_id)
3033 {
3034 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3035 return;
3036 }
3037
3038 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3039 if (!pEnchant)
3040 {
3041 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3042 return;
3043 }
3044
3045 // select enchantment duration
3046 uint32 duration;
3047
3048 // rogue family enchantments exception by duration
3049 if (m_spellInfo->Id == 38615)
3050 duration = 1800; // 30 mins
3051 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3053 duration = 3600; // 1 hour
3054 // shaman family enchantments
3056 duration = 1800; // 30 mins
3057 // other cases with this SpellVisual already selected
3058 else if (m_spellInfo->SpellVisual[0] == 215)
3059 duration = 1800; // 30 mins
3060 // some fishing pole bonuses except Glow Worm which lasts full hour
3061 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3062 duration = 600; // 10 mins
3063 // shaman rockbiter enchantments
3064 else if (m_spellInfo->SpellVisual[0] == 0)
3065 duration = 1800; // 30 mins
3066 else if (m_spellInfo->Id == 29702)
3067 duration = 300; // 5 mins
3068 else if (m_spellInfo->Id == 37360)
3069 duration = 300; // 5 mins
3070 // default case
3071 else
3072 duration = 3600; // 1 hour
3073
3074 // item can be in trade slot and have owner diff. from caster
3075 Player* item_owner = itemTarget->GetOwner();
3076 if (!item_owner)
3077 return;
3078
3079 // remove old enchanting before applying new if equipped
3081
3082 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3083
3084 // add new enchanting if equipped
3086
3087 item_owner->RemoveTradeableItem(itemTarget);
3089}
@ SPELLFAMILY_SHAMAN
Definition SharedDefines.h:3805
WeaponAttackType
Definition Unit.h:210
Definition Spell.h:119
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:379
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3412

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885 if (!unitTarget->IsAlive())
1886 return;
1887
1889 {
1891 return;
1892 }
1893
1894 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1895 return;
1896
1897 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1898
1901 return;
1902
1903 if (unitTarget->GetMaxPower(power) == 0)
1904 return;
1905
1906 // Some level depends spells
1907 int level_multiplier = 0;
1908 int level_diff = 0;
1909 switch (m_spellInfo->Id)
1910 {
1911 case 9512: // Restore Energy
1912 level_diff = m_caster->GetLevel() - 40;
1913 level_multiplier = 2;
1914 break;
1915 case 24571: // Blood Fury
1916 level_diff = m_caster->GetLevel() - 60;
1917 level_multiplier = 10;
1918 break;
1919 case 24532: // Burst of Energy
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 4;
1922 break;
1923 case 31930: // Judgements of the Wise
1924 case 63375: // Improved Stormstrike
1925 case 68082: // Glyph of Seal of Command
1927 break;
1928 case 48542: // Revitalize
1930 break;
1931 case 71132: // Glyph of Shadow Word: Pain
1932 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 if (level_diff > 0)
1939 damage -= level_multiplier * level_diff;
1940
1941 if (damage < 0)
1942 return;
1943
1945
1946 // Mad Alchemist's Potion
1947 if (m_spellInfo->Id == 45051)
1948 {
1949 // find elixirs on target
1950 bool guardianFound = false;
1951 bool battleFound = false;
1953 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1954 {
1955 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1956 if (!guardianFound)
1958 guardianFound = true;
1959 if (!battleFound)
1961 battleFound = true;
1962 if (battleFound && guardianFound)
1963 break;
1964 }
1965
1966 // get all available elixirs by mask and spell level
1967 std::set<uint32> availableElixirs;
1968 if (!guardianFound)
1969 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1970 if (!battleFound)
1971 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1972 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1973 {
1974 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1975 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1976 availableElixirs.erase(itr++);
1977 else
1978 ++itr;
1979 }
1980
1981 if (!availableElixirs.empty())
1982 {
1983 // cast random elixir on target
1985 }
1986 }
1987}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition SharedDefines.h:668
@ SPELLFAMILY_POTION
Definition SharedDefines.h:3807
SpellGroupSpecialFlags
Definition SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition SpellMgr.h:337
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition Unit.cpp:11349
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6569
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:133

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), GetSpellInfo(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), Unit::SendSpellDamageImmune(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1990{
1992 return;
1993
1994 if (!unitTarget)
1995 return;
1996 if (!unitTarget->IsAlive())
1997 return;
1998
1999 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2000 return;
2001
2002 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2003
2005 return;
2006
2007 uint32 maxPower = unitTarget->GetMaxPower(power);
2008 if (maxPower == 0)
2009 return;
2010
2011 uint32 gain = CalculatePct(maxPower, damage);
2013}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition Player.h:834
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:770

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4520{
4522 return;
4523
4524 Player* player = m_caster->ToPlayer();
4525 if (!player)
4526 return;
4527
4528 Item* foodItem = itemTarget;
4529 if (!foodItem)
4530 return;
4531
4532 Pet* pet = player->GetPet();
4533 if (!pet)
4534 return;
4535
4536 if (!pet->IsAlive())
4537 return;
4538
4539 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4540 if (benefit <= 0)
4541 return;
4542
4543 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4544
4545 uint32 count = 1;
4546 player->DestroyItemCount(foodItem, count, true);
4548
4549 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4550}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5109

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ SPELL_EFFECT_FORCE_CAST
Definition SharedDefines.h:929
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition SharedDefines.h:930
@ SPELLVALUE_BASE_POINT1
Definition SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition SpellDefines.h:113
Definition SpellDefines.h:165
void AddSpellMod(SpellValueMod mod, int32 value)
Definition SpellDefines.h:167

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4776{
4778 return;
4779
4780 // xinef: clear focus
4782
4784 data << m_caster->GetGUID();
4785
4787 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4788 Cell::VisitObjects(m_caster, notifier, dist);
4789
4790 // xinef: we should also force pets to remove us from current target
4791 Unit::AttackerSet attackerSet;
4792 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4793 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4794 attackerSet.insert(*itr);
4795
4796 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4797 (*itr)->AttackStop();
4798
4799 // Xinef: Mirror images code Initialize Images
4800 if (m_spellInfo->Id == 58836)
4801 {
4802 std::vector<Unit*> images;
4803 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4804 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4805 images.push_back(*itr);
4806
4807 if (images.empty())
4808 return;
4809
4810 UnitList targets;
4811 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4814 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4815 {
4816 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4817 continue;
4818
4819 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4820 {
4821 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4822 {
4823 SpellInfo const* si = spell->GetSpellInfo();
4824 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4825 {
4826 Creature* c = (*iter)->ToCreature();
4827 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4828 continue;
4829 }
4830
4831 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4832 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4833 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4834 {
4835 // at least one effect truly targets an unit, interrupt the spell
4836 interrupt = true;
4837 break;
4838 }
4839
4840 if (interrupt)
4841 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4842 }
4843 }
4844 }
4845 }
4846}
#define VISIBILITY_COMPENSATION
Definition ObjectDefines.h:26
@ CREATURE_ELITE_WORLDBOSS
Definition SharedDefines.h:2984
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition SharedDefines.h:628
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:102
std::list< Unit * > UnitList
Definition Unit.h:78
Definition GridNotifiers.h:852
bool IsDungeonBoss() const
Definition Creature.cpp:3180
ControlSet m_Controlled
Definition Unit.h:2032
void SendClearTarget()
Definition Unit.cpp:20084
@ SMSG_CLEAR_TARGET
Definition Opcodes.h:989
Definition GridNotifiers.h:134
Definition GridNotifiers.h:414
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
uint32 rank
Definition CreatureData.h:206

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, and Cell::VisitObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5932{
5934 return;
5935
5936 if (!gameObjTarget)
5937 return;
5938
5939 Unit* caster = m_originalCaster;
5940 if (!caster)
5941 return;
5942
5943 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5945 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5946 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5948}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2269
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:10086
Definition DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition DBCStructure.h:951

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5962{
5964 return;
5965
5967 return;
5968
5971}
GameObjectDestructibleState
Definition SharedDefines.h:1637
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2332

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1561 }
1562 else if (m_spellInfo->Id != 33778) // not lifebloom
1563 {
1564 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1565 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1566 }
1567
1568 // Implemented this way as there is no other way to do it currently (that I know :P)...
1569 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1570 {
1572 {
1573 m_damage = 0;
1574 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1575 return;
1576 }
1577 }
1578
1579 m_damage -= addhealth;
1580 }
1581}
@ SPELLFAMILY_DRUID
Definition SharedDefines.h:3801
@ SPELLFAMILY_DEATHKNIGHT
Definition SharedDefines.h:3809
@ AURA_STATE_SWIFTMEND
Definition SharedDefines.h:1318
@ SPELL_SCHOOL_MASK_HOLY
Definition SharedDefines.h:309
@ SPELL_AURA_PERIODIC_HEAL
Definition SpellAuraDefines.h:71
@ DOT
Definition Unit.h:252
SpellInfo const * GetSpellInfo() const
Definition SpellAuraEffects.h:54
uint32 GetId() const
Definition SpellAuraEffects.cpp:433
Unit * GetCaster() const
Definition SpellAuraEffects.h:47
Aura * GetBase() const
Definition SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition SpellAuraEffects.h:48
int32 GetAmount() const
Definition SpellAuraEffects.h:64
uint32 TargetAuraState
Definition SpellInfo.h:340
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1083

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3677{
3679 return;
3680
3681 if (!unitTarget || !unitTarget->IsAlive())
3682 return;
3683
3685 {
3687 return;
3688 }
3689
3690 int32 addhealth = 0;
3691
3692 // damage == 0 - heal for caster max health
3693 if (damage == 0)
3694 addhealth = m_caster->GetMaxHealth();
3695 else
3696 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3697
3698 m_healing += addhealth;
3699}
uint32 GetMaxHealth() const
Definition Unit.h:1071

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), Unit::HasUnitState(), Unit::IsAlive(), m_caster, m_healing, Unit::SendSpellDamageImmune(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1619{
1621 return;
1622
1623 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1624 return;
1625
1628
1629 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1630
1631 // xinef: handled in spell.cpp
1632 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1633
1634 m_damage += damage;
1635 // get max possible damage, don't count overkill for heal
1636 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1637
1638 //if (m_caster->IsAlive())
1639 //{
1640 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1641 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1642
1643 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1644 //}
1645}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:11869
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:11693

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4484{
4486 return;
4487
4488 if (!unitTarget)
4489 return;
4490
4491 Player* player = unitTarget->ToPlayer();
4492 if (!player)
4493 {
4494 return;
4495 }
4496
4497 uint8 currentDrunk = player->GetDrunkValue();
4498 int32 drunkMod = damage;
4499
4500 if (drunkMod == 0)
4501 return;
4502
4503 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4504 // In addition, we would not want currentDrunk to become more than 100.
4505 // So before adding the values, let's check that everything is fine.
4506 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4507 currentDrunk = 100;
4508 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4509 currentDrunk = 0;
4510 else
4511 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4512
4513 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4514
4515 if (currentDrunk == 100 && roll_chance_i(25))
4516 player->CastSpell(player, 67468, false); // Drunken Vomit
4517}
uint8 GetDrunkValue() const
Definition Player.h:2169
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:987

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ CHEAT_GOD
Definition Player.h:994
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:308
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition Unit.cpp:824
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:845

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3702{
3704 return;
3705
3706 if (!unitTarget || !unitTarget->IsAlive())
3707 return;
3708
3710 // also exist case: apply cooldown to interrupted cast only and to all spells
3711 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3713 {
3715 {
3716 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3717 // check if we can interrupt spell
3718 if ((spell->getState() == SPELL_STATE_CASTING
3719 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3723 {
3724 if (m_originalCaster)
3725 {
3727 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3728 }
3729 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3731 }
3732 }
3733 }
3734}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:545
CurrentSpellTypes
Definition Unit.h:538
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:541
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:542
uint32 ChannelInterruptFlags
Definition SpellInfo.h:354
uint32 InterruptFlags
Definition SpellInfo.h:352
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5082
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4117
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:14886
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1543

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:244
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1153
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#define INVALID_HEIGHT
Definition GridTerrainData.h:27
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:326
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5724{
5726 return;
5727
5728 if (!unitTarget)
5729 return;
5730
5732 if (!player)
5733 {
5734 return;
5735 }
5736
5737 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5738 if (!creatureEntry)
5739 {
5740 if (m_spellInfo->Id == 42793) // Burn Body
5741 creatureEntry = 24008; // Fallen Combatant
5742 }
5743
5744 if (creatureEntry)
5745 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5746}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:12731

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5710{
5712 return;
5713
5714 if (!unitTarget)
5715 return;
5716
5718 {
5719 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5720 }
5721}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4980{
4982 return;
4983
4984 if (!unitTarget)
4985 return;
4986
4987 // Xinef: allow entry specific spells to skip those checks
4988 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4989 {
4991 return;
4992
4993 if (unitTarget->GetVehicle())
4994 return;
4995
4996 if (Creature* creatureTarget = unitTarget->ToCreature())
4997 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4998 return;
4999 }
5000
5001 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5003 return;
5004
5005 // Instantly interrupt non melee spells being casted
5008
5009 float ratio = 0.1f;
5010 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5011 float speedz = float(damage) * ratio;
5012 if (speedxy <= 0.1f && speedz <= 0.1f)
5013 return;
5014
5015 float x, y;
5016 Unit* reflectionSource = m_reflectionTarget;
5017
5018 if (!reflectionSource && !m_reflectionTargetGuid.IsEmpty())
5019 {
5021 reflectionSource = resolvedSource;
5022 }
5023
5024 if (reflectionSource)
5025 {
5026 reflectionSource->GetPosition(x, y);
5027 }
5028 else if (!m_reflectionTargetGuid.IsEmpty())
5029 {
5032 }
5033 else if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5034 {
5035 if (m_targets.HasDst())
5036 destTarget->GetPosition(x, y);
5037 else
5038 return;
5039 }
5040 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5041 {
5042 m_caster->GetPosition(x, y);
5043 }
5044
5045 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5046
5047 if (unitTarget->IsPlayer())
5048 {
5049 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5050 }
5051}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition SharedDefines.h:933
@ CREATURE_TYPE_GIANT
Definition SharedDefines.h:2643
@ CREATURE_TYPE_BEAST
Definition SharedDefines.h:2639
bool IsEmpty() const
Definition ObjectGuid.h:161
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4189
uint32 GetCreatureType() const
Definition Unit.cpp:15212
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:19173

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), ObjectGuid::IsEmpty(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_reflectionTarget, m_reflectionTargetGuid, m_reflectionTargetPosition, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4706{
4708 return;
4709
4710 if (!unitTarget || unitTarget->IsInFlight())
4711 return;
4712
4713 if (!m_targets.HasDst())
4714 return;
4715
4716 Position dstpos = destTarget->GetPosition();
4718}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:19737

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5054{
5056 return;
5057
5058 if (!unitTarget)
5059 return;
5060
5061 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5062 float speedz = damage / 10.0f;
5063 //1891: Disengage
5065
5066 if (m_caster->IsPlayer())
5067 {
5068 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5069 }
5070
5071 // xinef: changes fall time
5072 if (m_caster->IsPlayer())
5074}
@ SPELLFAMILY_HUNTER
Definition SharedDefines.h:3803
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:19285

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3262{
3264 return;
3265
3266 if (!unitTarget)
3267 return;
3268
3269 if (unitTarget->ToPlayer())
3270 {
3271 EffectLearnSpell(effIndex);
3272 return;
3273 }
3274 Pet* pet = unitTarget->ToPet();
3275 if (!pet)
3276 return;
3277
3278 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3279 if (!learn_spellproto)
3280 return;
3281
3282 pet->learnSpell(learn_spellproto->Id);
3284 pet->GetOwner()->PetSpellInitialize();
3285}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1915
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2548

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2779{
2781 return;
2782
2783 if (!unitTarget->IsPlayer())
2784 return;
2785
2786 if (damage < 0)
2787 return;
2788
2789 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2790 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2791 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2792}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5512
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5326

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2549{
2551 return;
2552
2553 if (!unitTarget)
2554 return;
2555
2556 if (!unitTarget->IsPlayer())
2557 {
2558 if (unitTarget->ToPet())
2559 EffectLearnPetSpell(effIndex);
2560 return;
2561 }
2562
2563 Player* player = unitTarget->ToPlayer();
2564
2565 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2566 player->learnSpell(spellToLearn);
2567
2568 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2569 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2570}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3305
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3261

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5533{
5535 return;
5536
5537 if (!m_caster->IsPlayer())
5538 return;
5539
5540 Player* p_caster = m_caster->ToPlayer();
5542 return;
5543
5544 if (itemTarget->GetCount() < 5)
5545 return;
5546
5547 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5548 {
5549 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5550 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5551 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5552 }
5553
5555}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:51
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7809
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:762

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5366{
5368 return;
5369
5370 if (!unitTarget)
5371 return;
5372
5374}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition Unit.h:936

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2082{
2084 return;
2085
2086 if (!m_caster->IsPlayer())
2087 {
2088 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2089 return;
2090 }
2091
2092 Player* player = m_caster->ToPlayer();
2093
2094 uint32 lockId = 0;
2095 ObjectGuid guid;
2096
2097 // Get lockId
2098 if (gameObjTarget)
2099 {
2100 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2101 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2102 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2103 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2104 {
2105 //CanUseBattlegroundObject() already called in CheckCast()
2106 // in battleground check
2107 if (Battleground* bg = player->GetBattleground())
2108 {
2109 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2110 return;
2111 }
2112 }
2113 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2114 {
2115 //CanUseBattlegroundObject() already called in CheckCast()
2116 // in battleground check
2117 if (Battleground* bg = player->GetBattleground())
2118 {
2119 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2120 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2121 return;
2122 }
2123 }
2124 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2125 {
2128 {
2130 }
2131 return;
2132 }
2134 // handle outdoor pvp object opening, return true if go was registered for handling
2135 // these objects must have been spawned by outdoorpvp!
2136 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2137 return;
2138 lockId = goInfo->GetLockId();
2139 guid = gameObjTarget->GetGUID();
2140 }
2141 else if (itemTarget)
2142 {
2143 lockId = itemTarget->GetTemplate()->LockID;
2144 guid = itemTarget->GetGUID();
2145 }
2146 else
2147 {
2148 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2149 return;
2150 }
2151
2152 SkillType skillId = SKILL_NONE;
2153 int32 reqSkillValue = 0;
2154 int32 skillValue;
2155
2156 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2157 if (res != SPELL_CAST_OK)
2158 {
2159 SendCastResult(res);
2160 return;
2161 }
2162
2163 if (gameObjTarget)
2164 SendLoot(guid, LOOT_SKINNING);
2165 else if (itemTarget)
2166 {
2168 if (Player* itemOwner = itemTarget->GetOwner())
2169 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2170 }
2171
2172 // not allow use skill grow at item base open
2173 if (!m_CastItem && skillId != SKILL_NONE)
2174 {
2175 // update skill if really known
2176 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2177 {
2178 if (gameObjTarget)
2179 {
2180 // Allow one skill-up until respawned
2181 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2182 {
2184 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2185 }
2186
2187 }
2188 else if (itemTarget)
2189 {
2190 // Do one skill-up
2191 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2192 }
2193 }
2194 }
2196}
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
@ ITEM_FIELD_FLAG_UNLOCKED
Definition ItemTemplate.h:111
@ ITEM_CHANGED
Definition Item.h:210
@ LOOT_SKINNING
Definition LootMgr.h:85
#define sOutdoorPvPMgr
Definition OutdoorPvPMgr.h:102
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1595
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1581
@ BATTLEGROUND_EY
Definition SharedDefines.h:3753
@ ITEM_FIELD_FLAGS
Definition UpdateFields.h:42
Unit * GetOwner() const
Definition GameObject.cpp:1219
LootState getLootState() const
Definition GameObject.h:223
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2434
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3066
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3060
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:714
Definition Object.h:104
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5097
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2015
Definition GameObjectData.h:31
struct GameObjectTemplate::@232::@243 goober
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:510
struct GameObjectTemplate::@232::@235 button
uint32 noDamageImmune
Definition GameObjectData.h:48
uint32 losOK
Definition GameObjectData.h:64
uint32 GetLockId() const
Definition GameObjectData.h:427

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4688{
4690 return;
4691
4692 if (m_caster->IsPlayer())
4693 m_caster->ToPlayer()->SetCanParry(true);
4694}
void SetCanParry(bool value)
Definition Player.cpp:13122

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1845{
1847 return;
1848
1849 if (!m_spellAura)
1850 {
1852 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1853
1854 // Caster not in world, might be spell triggered from aura removal
1855 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1856 return;
1857 DynamicObject* dynObj = new DynamicObject();
1859 {
1860 delete dynObj;
1861 return;
1862 }
1863
1865 {
1866 m_spellAura = aura;
1869 }
1870 else
1871 return;
1872 }
1873
1876}
#define MAX_EFFECT_MASK
Definition DBCStructure.h:1639
@ DYNAMIC_OBJECT_AREA_SPELL
Definition DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, DynamicObject, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6123{
6125 return;
6126
6127 if (!unitTarget)
6128 return;
6129
6130 Player* player = unitTarget->ToPlayer();
6131 if (!player)
6132 {
6133 return;
6134 }
6135
6136 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6137
6138 if (!sSoundEntriesStore.LookupEntry(soundid))
6139 {
6140 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6141 return;
6142 }
6143
6145}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6176{
6178 return;
6179
6180 if (!unitTarget)
6181 return;
6182
6183 Player* player = unitTarget->ToPlayer();
6184 if (!player)
6185 {
6186 return;
6187 }
6188
6189 switch (m_spellInfo->Id)
6190 {
6191 case 58730: // Restricted Flight Area
6192 case 58600: // Restricted Flight Area
6194 break;
6195 default:
6196 break;
6197 }
6198
6199 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6200
6201 if (!sSoundEntriesStore.LookupEntry(soundId))
6202 {
6203 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6204 return;
6205 }
6206
6207 player->PlayDirectSound(soundId, player);
6208}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:759
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:105
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:2908

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5066
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:14238
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1243

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2308{
2310 return;
2311
2312 if (!m_caster->IsPlayer())
2313 return;
2314 Player* p_target = m_caster->ToPlayer();
2315
2317 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2318 {
2319 p_target->AddWeaponProficiency(subClassMask);
2321 }
2322 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2323 {
2324 p_target->AddArmorProficiency(subClassMask);
2326 }
2327}
uint32 GetArmorProficiency() const
Definition Player.h:1360
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10093
uint32 GetWeaponProficiency() const
Definition Player.h:1359
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1358
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1357
int32 EquippedItemSubClassMask
Definition SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2691{
2693 EffectNULL(effIndex);
2694}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5139{
5141 return;
5142
5143 if (!unitTarget)
5144 return;
5145
5146 Position pos;
5147 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5148 {
5149 if (m_targets.HasDst())
5150 pos.Relocate(*destTarget);
5151 else
5152 return;
5153 }
5154 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5155 {
5156 // Xinef: Increase Z position a little bit, should protect from falling through textures
5158 }
5159
5160 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5161 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5162
5163 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5164
5165 if (unitTarget->IsPlayer())
5166 {
5167 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5168 }
5169}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition SharedDefines.h:934

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5077{
5079 return;
5080
5081 if (!unitTarget)
5082 return;
5083
5084 Player* player = unitTarget->ToPlayer();
5085 if (!player)
5086 {
5087 return;
5088 }
5089
5090 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5091
5092 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5093
5094 if (!quest)
5095 return;
5096
5097 // Player has never done this quest
5098 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5099 return;
5100
5101 // remove all quest entries for 'entry' from quest log
5102 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5103 {
5104 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5105 if (logQuest == quest_id)
5106 {
5107 player->SetQuestSlot(slot, 0);
5108
5109 // we ignore unequippable quest items in this case, it's still be equipped
5110 player->TakeQuestSourceItem(logQuest, false);
5111
5112 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5113 {
5114 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5115 player->UpdatePvPState();
5116 }
5117 }
5118 }
5119
5120 player->RemoveRewardedQuest(quest_id);
5121 player->RemoveActiveQuest(quest_id, false);
5122}
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:33
@ QUEST_STATUS_NONE
Definition QuestDef.h:100
bool HasPvPForcingQuest() const
Definition PlayerQuest.cpp:2495
void UpdatePvPState()
Definition PlayerUpdates.cpp:1436
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1482
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1486
PvPInfo pvpInfo
Definition Player.h:1842
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1363
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1495
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1430
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1513
Definition QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition QuestDef.h:221
bool IsHostile
Definition Player.h:356
bool IsInHostileArea
Definition Player.h:357

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4747{
4749 return;
4750
4751 if (!unitTarget)
4752 return;
4753
4754 Player* player = unitTarget->ToPlayer();
4755 if (!player)
4756 {
4757 return;
4758 }
4759
4760 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4761 if (questId)
4762 {
4763 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4764 if (!quest)
4765 return;
4766
4767 uint16 logSlot = player->FindQuestSlot(questId);
4768 if (logSlot < MAX_QUEST_LOG_SIZE)
4769 player->AreaExploredOrEventHappens(questId);
4770 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4771 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4772 }
4773}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1782
bool CanTakeQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition PlayerQuest.cpp:880
void AreaExploredOrEventHappens(uint32 questId)
Definition PlayerQuest.cpp:1791

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, Player::SetRewardedQuest(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5749{
5751 return;
5752
5753 if (!unitTarget)
5754 return;
5755
5756 if (Player* player = unitTarget->ToPlayer())
5757 {
5758 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5759 }
5760}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5763{
5765 return;
5766
5767 if (!unitTarget)
5768 return;
5769
5770 Player* player = unitTarget->ToPlayer();
5771 if (!player)
5772 return;
5773
5774 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5775 {
5776 if (!player->CanTakeQuest(quest, false))
5777 return;
5778
5779 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5780 player->AddQuestAndCheckCompletion(quest, player);
5781
5782 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5783 }
5784}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition PlayerQuest.cpp:421
PlayerMenu * PlayerTalkClass
Definition Player.h:2241

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6265{
6267 return;
6268
6269 if (!unitTarget || !unitTarget->IsPlayer())
6270 return;
6271
6272 Player* player = m_caster->ToPlayer();
6273
6274 if (!player)
6275 return;
6276
6277 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6278
6279 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6280 if (!pProto)
6281 {
6282 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6283 return;
6284 }
6285
6286 if (Item* pItem = player->GetItemByEntry(item_id))
6287 {
6288 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6289 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6290 pItem->SetState(ITEM_CHANGED, player);
6291 }
6292}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5923{
5925 return;
5926
5927 if (unitTarget)
5929}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition Unit.h:943

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6211{
6213 return;
6214
6215 if (!unitTarget)
6216 return;
6217 // there may be need of specifying casterguid of removed auras
6218 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6219}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6111{
6113 return;
6114
6115 if (!unitTarget || !unitTarget->IsCreature() ||
6117 return;
6118
6120}
@ UNIT_CAN_BE_RENAMED
Definition UnitDefines.h:149
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:900
PetType getPetType() const
Definition Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4721{
4723 return;
4724
4725 if (!unitTarget)
4726 return;
4727
4728 Player* player = unitTarget->ToPlayer();
4729 if (!player)
4730 {
4731 return;
4732 }
4733
4734 float repChange = static_cast<float>(damage);
4735
4736 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4737
4738 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4739 if (!factionEntry)
4740 return;
4741
4742 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4743 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4744}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition SharedDefines.h:198
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:5866
ReputationMgr & GetReputationMgr()
Definition Player.h:2123
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition ReputationMgr.h:117
Definition DBCStructure.h:907

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4639{
4641 return;
4642
4643 if (!unitTarget)
4644 return;
4645
4646 if (!unitTarget)
4647 return;
4648
4649 Player* target = unitTarget->ToPlayer();
4650 if (!target)
4651 {
4652 return;
4653 }
4654
4655 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4656 return;
4657
4658 if (target->isResurrectRequested()) // already have one active request
4659 return;
4660
4661 uint32 health = target->CountPctFromMaxHealth(damage);
4663
4664 ExecuteLogEffectResurrect(effIndex, target);
4665
4667 SendResurrectRequest(target);
4668}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1811
bool isResurrectRequested() const
Definition Player.h:1823
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5127
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5189

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5215{
5217 return;
5218
5219 if (damage < 0)
5220 return;
5221
5222 Player* player = m_caster->ToPlayer();
5223 if (!player)
5224 {
5225 return;
5226 }
5227
5228 Pet* pet = player->GetPet();
5229 if (!pet)
5230 {
5231 // Position passed to SummonPet is irrelevant with current implementation,
5232 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5233 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5234 return;
5235 }
5236
5238 if (pet->IsAlive())
5239 {
5240 return;
5241 }
5242
5243 // Reposition the pet's corpse before reviving so as not to grab aggro
5244 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5245 float x, y, z; // Will be used later to reposition the pet if we have one
5246 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5247 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5248 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5252 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5254 pet->SetDisplayId(pet->GetNativeDisplayId());
5255
5256 // xinef: restore movement
5257 if (auto ci = pet->GetCharmInfo())
5258 {
5259 ci->SetIsAtStay(false);
5260 ci->SetIsFollowing(false);
5261 }
5262
5264}
constexpr float PET_FOLLOW_DIST
Definition PetDefines.h:206
@ SUMMON_PET
Definition PetDefines.h:32
@ UNIT_DYNFLAG_NONE
Definition SharedDefines.h:3370
@ UNIT_STATE_POSSESSED
Definition UnitDefines.h:186
@ UNIT_STATE_ALL_STATE
Definition UnitDefines.h:224
float GetFollowAngle() const override
Definition TemporarySummon.h:83
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition Pet.cpp:626
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition Pet.cpp:2424
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:8978
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:754
void SetHealth(uint32 val)
Definition Unit.cpp:15508
uint32 GetNativeDisplayId() const
Definition Unit.h:1930
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:734
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition Object.cpp:2717

References Alive, Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4023{
4025 return;
4026
4027 if (!unitTarget)
4028 return;
4029
4031 {
4033 // Xinef: replaced with CombatStop(false)
4036
4037 // Night Elf: Shadowmeld only resets threat temporarily
4038 if (m_spellInfo->Id != 59646)
4040
4041 if (unitTarget->IsPlayer())
4042 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4043 }
4044 else
4045 {
4046 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4047 unitTarget->CombatStop(true);
4048 }
4049
4050 UnitList targets;
4051 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4054 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4055 {
4056 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4057 continue;
4058
4060 {
4061 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4062 {
4063 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4064 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4065 {
4066 Creature* c = (*iter)->ToCreature();
4067 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4068 continue;
4069 }
4070 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4071 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4072 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4073 {
4074 // at least one effect truly targets an unit, interrupt the spell
4075 interrupt = true;
4076 break;
4077 }
4078 if (interrupt)
4079 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4080 }
4081 }
4082 }
4083
4084 // Xinef: Set last sanctuary time
4086}
#define CURRENT_MAX_SPELL
Definition Unit.h:546
void UpdateVisibility(bool checkThreat)
Definition HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition HostileRefMgr.cpp:85
virtual bool IsEncounterInProgress() const
Definition InstanceScript.cpp:137
void SendAttackSwingCancelAttack()
Definition PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition Unit.cpp:10513
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition Unit.cpp:10561
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:10480

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
@ EFFECT_2
Definition SharedDefines.h:33
@ POWER_ENERGY
Definition SharedDefines.h:283
@ SPELLFAMILY_PRIEST
Definition SharedDefines.h:3800
@ AURA_STATE_CONFLAGRATE
Definition SharedDefines.h:1317
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:179
@ FORM_SHADOW
Definition UnitDefines.h:95
@ MINDAMAGE
Definition Unit.h:137
@ MAXDAMAGE
Definition Unit.h:138
uint8 GetStackAmount() const
Definition SpellAuras.h:148
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition Unit.cpp:15458
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:14859
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4994
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.h:897
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.h:1400

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3787{
3789 return;
3790
3792
3794 {
3796 {
3797 switch (m_spellInfo->Id)
3798 {
3799 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3800 case 22539:
3801 case 22972:
3802 case 22975:
3803 case 22976:
3804 case 22977:
3805 case 22978:
3806 case 22979:
3807 case 22980:
3808 case 22981:
3809 case 22982:
3810 case 22983:
3811 case 22984:
3812 case 22985:
3813 {
3814 if (!unitTarget || !unitTarget->IsAlive())
3815 return;
3816
3817 // Onyxia Scale Cloak
3818 if (unitTarget->HasAura(22683))
3819 return;
3820
3821 // Shadow Flame
3822 m_caster->CastSpell(unitTarget, 22682, true);
3823 return;
3824 }
3825 // Plant Warmaul Ogre Banner
3826 case 32307:
3827 if (Player* caster = m_caster->ToPlayer())
3828 {
3829 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3830 if (Creature* target = unitTarget->ToCreature())
3831 {
3832 target->setDeathState(DeathState::Corpse);
3833 target->RemoveCorpse();
3834 }
3835 }
3836 break;
3837 // SOTA defender teleport
3838 case 54640:
3839 {
3840 if (Player* player = unitTarget->ToPlayer())
3841 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3842 {
3843 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3844 {
3845 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3846 bg->DefendersPortalTeleport(dportal, player);
3847 }
3848 }
3849 return;
3850 }
3851 /*// Mug Transformation
3852 case 41931:
3853 {
3854 if (!m_caster->IsPlayer())
3855 return;
3856
3857 uint8 bag = 19;
3858 uint8 slot = 0;
3859 Item* item = nullptr;
3860
3861 while (bag) // 256 = 0 due to var type
3862 {
3863 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3864 if (item && item->GetEntry() == 38587)
3865 break;
3866
3867 ++slot;
3868 if (slot == 39)
3869 {
3870 slot = 0;
3871 ++bag;
3872 }
3873 }
3874 if (bag)
3875 {
3876 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3877 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3878 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3879 m_caster->CastSpell(m_caster, 42518, true);
3880 return;
3881 }
3882 break;
3883 }*/
3884 // Roll Dice - Decahedral Dwarven Dice
3885 case 47770:
3886 {
3887 char buf[128];
3888 const char* gender = "his";
3889 if (m_caster->getGender() > 0)
3890 gender = "her";
3891 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3892 m_caster->TextEmote(buf);
3893 break;
3894 }
3895 case 52173: // Coyote Spirit Despawn
3896 case 60243: // Blood Parrot Despawn
3899 return;
3900 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3901 {
3903 return;
3904
3906
3907 return;
3908 }
3909 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3910 {
3911 if (!m_caster->IsPlayer())
3912 return;
3913
3914 // Delete item from inventory at death
3916
3917 return;
3918 }
3919 case 58418: // Portal to Orgrimmar
3920 case 58420: // Portal to Stormwind
3921 {
3922 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3923 return;
3924
3925 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3926 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3927
3929 unitTarget->CastSpell(unitTarget, spellID, true);
3930
3931 return;
3932 }
3933 // Stoneclaw Totem
3934 case 55328: // Rank 1
3935 case 55329: // Rank 2
3936 case 55330: // Rank 3
3937 case 55332: // Rank 4
3938 case 55333: // Rank 5
3939 case 55335: // Rank 6
3940 case 55278: // Rank 7
3941 case 58589: // Rank 8
3942 case 58590: // Rank 9
3943 case 58591: // Rank 10
3944 {
3945 int32 basepoints0 = damage;
3946 // Cast Absorb on totems
3947 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
3948 {
3949 if (!unitTarget->m_SummonSlot[slot])
3950 continue;
3951
3953 if (totem && totem->IsTotem())
3954 {
3955 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3956 }
3957 }
3958 // Glyph of Stoneclaw Totem
3959 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3960 {
3961 basepoints0 *= aur->GetAmount();
3962 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3963 }
3964 break;
3965 }
3966 case 61263: // for item Intravenous Healing Potion (44698)
3967 {
3968 if (!m_caster || !unitTarget)
3969 return;
3970
3971 m_caster->CastSpell(m_caster, 61267, true);
3972 m_caster->CastSpell(m_caster, 61268, true);
3973 return;
3974 }
3975 }
3976 break;
3977 }
3978 case SPELLFAMILY_ROGUE:
3979 {
3980 switch (m_spellInfo->Id)
3981 {
3982 // Master of Subtlety
3983 case 31666:
3984 {
3985 if (!unitTarget)
3986 return;
3987
3988 Aura* mos = unitTarget->GetAura(31665);
3989 if (mos)
3990 {
3991 mos->SetMaxDuration(6000);
3992 mos->SetDuration(6000, true);
3993 }
3994
3995 break;
3996 }
3997 // Overkill
3998 case 58428:
3999 {
4000 if (!unitTarget)
4001 return;
4002
4003 Aura* overkill = unitTarget->GetAura(58427);
4004 if (overkill)
4005 {
4006 overkill->SetMaxDuration(20000);
4007 overkill->SetDuration(20000, true);
4008 }
4009
4010 break;
4011 }
4012 }
4013 break;
4014 }
4015 }
4016
4017 // normal DB scripted effect
4018 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4020}
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:101
@ BATTLEGROUND_SA
Definition SharedDefines.h:3755
Class for manage Strand of Ancient battleground.
Definition BattlegroundSA.h:428
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition BattlegroundSA.cpp:587
void DespawnOrUnsummon(Milliseconds msTimeToDespawn=0ms, Seconds forcedRespawnTimer=0s)
Definition Creature.cpp:2182
virtual void UnSummon(Milliseconds msTime=0ms)
Definition TemporarySummon.cpp:287
uint8 getGender() const
Definition Unit.h:831
bool IsSummon() const
Definition Unit.h:777
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition Unit.cpp:21024
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition Object.cpp:2459
std::string const & GetName() const
Definition Object.h:525

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), Corpse, damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM_FIRE, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4849{
4851 return;
4852
4853 if (!m_caster || m_caster->IsAlive())
4854 return;
4855 if (!m_caster->IsPlayer())
4856 return;
4857 if (!m_caster->IsInWorld())
4858 return;
4859
4860 uint32 health = 0;
4861 uint32 mana = 0;
4862
4863 // flat case
4864 if (damage < 0)
4865 {
4866 health = uint32(-damage);
4867 mana = m_spellInfo->Effects[effIndex].MiscValue;
4868 }
4869 // percent case
4870 else
4871 {
4875 }
4876
4877 Player* player = m_caster->ToPlayer();
4878 player->ResurrectPlayer(0.0f);
4879
4880 player->SetHealth(health);
4881 player->SetPower(POWER_MANA, mana);
4882 player->SetPower(POWER_RAGE, 0);
4883 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4884
4885 player->SpawnCorpseBones();
4886}
@ POWER_RAGE
Definition SharedDefines.h:281
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4684
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4466
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:15596

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
@ TARGET_FLAG_UNIT_MASK
Definition SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition SpellInfo.h:70
Definition Object.h:472
ZoneScript * GetZoneScript() const
Definition Object.h:627
Definition ZoneScript.h:26

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5125{
5127 return;
5128
5129 if (!unitTarget)
5130 return;
5131
5132 if (Player* player = unitTarget->ToPlayer())
5133 {
5134 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5135 }
5136}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5558{
5560 return;
5561
5562 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5563}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4889{
4891 return;
4892
4893 if (!unitTarget->IsCreature())
4894 return;
4895 if (!m_caster->IsPlayer())
4896 return;
4897
4898 Creature* creature = unitTarget->ToCreature();
4899 int32 targetLevel = creature->GetLevel();
4900
4901 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4902
4906
4907 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4908
4909 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4910
4911 // Double chances for elites
4912 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4913}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3371
bool isElite() const
Definition Creature.h:116
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:124

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5589{
5591 return;
5592
5593 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5594 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5595 return;
5596
5598
5599 // We have a corpse object as the target.
5600 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5602}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7770
void RemoveObjectTarget()
Definition Spell.cpp:321

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_targets, Player::RemovedInsignia(), SpellCastTargets::RemoveObjectTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6148{
6150 return;
6151
6152 if (!unitTarget)
6153 return;
6154
6155 if (Player* player = unitTarget->ToPlayer())
6156 {
6157 player->UpdateSpecCount(damage);
6158 }
6159}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5570{
5572 return;
5573
5574 /*
5575 if (!unitTarget->IsPlayer())
5576 return;
5577 if (!unitTarget->IsInWorld())
5578 return;
5579
5580 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5581 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5582 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5583 unitTarget->ToPlayer()->SpawnCorpseBones();
5584 */
5585}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5605{
5607 return;
5608
5609 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5610
5611 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5612 return;
5613
5614 DispelChargesList steal_list;
5615
5616 // Create dispel mask by dispel type
5617 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5618 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5619 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5620 {
5621 Aura* aura = itr->second;
5623 if (!aurApp)
5624 continue;
5625
5626 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5627 {
5628 // Need check for passive? this
5629 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5630 continue;
5631
5632 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5633 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5634 // Polymorph instead of 1 / (5 + 1) -> 16%.
5635 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5636 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5637 if (charges > 0)
5638 steal_list.push_back(std::make_pair(aura, charges));
5639 }
5640 }
5641
5642 if (steal_list.empty())
5643 return;
5644
5645 // Ok if exist some buffs for dispel try dispel it
5646 uint32 failCount = 0;
5647 DispelList success_list;
5648 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5649 // dispel N = damage buffs (or while exist buffs for dispel)
5650 for (int32 count = 0; count < damage && !steal_list.empty();)
5651 {
5652 // Random select buff for dispel
5653 DispelChargesList::iterator itr = steal_list.begin();
5654 std::advance(itr, urand(0, steal_list.size() - 1));
5655
5656 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5657 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5658 if (!chance)
5659 {
5660 steal_list.erase(itr);
5661 continue;
5662 }
5663 else
5664 {
5665 if (roll_chance_i(chance))
5666 {
5667 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5668 --itr->second;
5669 if (itr->second <= 0)
5670 steal_list.erase(itr);
5671 }
5672 else
5673 {
5674 if (!failCount)
5675 {
5676 // Failed to dispell
5677 dataFail << m_caster->GetGUID(); // Caster GUID
5678 dataFail << unitTarget->GetGUID(); // Victim GUID
5679 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5680 }
5681 ++failCount;
5682 dataFail << uint32(itr->first->GetId()); // Spell Id
5683 }
5684 ++count;
5685 }
5686 }
5687
5688 if (failCount)
5689 m_caster->SendMessageToSet(&dataFail, true);
5690
5691 if (success_list.empty())
5692 return;
5693
5694 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5695 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5696 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5697 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5698 dataSuccess << uint8(0); // not used
5699 dataSuccess << uint32(success_list.size()); // count
5700 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5701 {
5702 dataSuccess << uint32(itr->first); // Spell Id
5703 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5704 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5705 }
5706 m_caster->SendMessageToSet(&dataSuccess, true);
5707}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition SharedDefines.h:662
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition SharedDefines.h:547
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition SpellEffects.cpp:2572
bool IsPositive() const
Definition SpellAuras.h:68
uint8 GetCharges() const
Definition SpellAuras.h:141
bool IsPassive() const
Definition SpellAuras.cpp:1082
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition Unit.cpp:5075
@ SMSG_SPELLSTEALLOG
Definition Opcodes.h:849

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4180{
4182 return;
4183
4184 if (!m_caster->IsPlayer())
4185 return;
4186
4187 Player* target = m_caster->ToPlayer();
4188 if (target->IsInFlight())
4189 return;
4190
4191 // xinef: if player is dead - teleport to graveyard
4192 if (!target->IsAlive())
4193 {
4194 if (target->HasPreventResurectionAura())
4195 return;
4196
4197 // xinef: player is in corpse
4198 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4199 target->BuildPlayerRepop();
4200 target->RepopAtGraveyard();
4201 return;
4202 }
4203
4204 // xinef: no hearthstone in bag or on cooldown
4205 Item* hearthStone = target->GetItemByEntry(6948);
4206 if (!hearthStone || target->HasSpellCooldown(8690))
4207 {
4208 float o = rand_norm() * 2 * M_PI;
4209 Position pos = *target;
4210 target->MovePositionToFirstCollision(pos, 5.0f, o);
4211 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4212 return;
4213 }
4214
4215 // xinef: we have hearthstone not on cooldown, just use it
4217}
@ PLAYER_FLAGS_GHOST
Definition Player.h:472
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:4916
void BuildPlayerRepop()
Definition Player.cpp:4418
bool HasPreventResurectionAura() const
Definition Unit.h:1762
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2876

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasPlayerFlag(), Unit::HasPreventResurectionAura(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2199{
2201 return;
2202
2203 if (!m_caster->IsPlayer())
2204 return;
2205
2206 Player* player = m_caster->ToPlayer();
2207
2208 // applied only to using item
2209 if (!m_CastItem)
2210 return;
2211
2212 // ... only to item in own inventory/bank/equip_slot
2213 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2214 return;
2215
2216 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2217 if (!newitemid)
2218 return;
2219
2220 uint16 pos = m_CastItem->GetPos();
2221
2222 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2223 if (!pNewItem)
2224 return;
2225
2226 // Client-side enchantment durations update
2228
2232
2234 {
2236 player->DurabilityLoss(pNewItem, lossPercent);
2237 }
2238
2239 if (player->IsInventoryPos(pos))
2240 {
2241 ItemPosCountVec dest;
2242 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2243 if (msg == EQUIP_ERR_OK)
2244 {
2245 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2246
2247 // prevent crash at access and unexpected charges counting with item update queue corrupt
2249 m_targets.SetItemTarget(nullptr);
2250
2251 m_CastItem = nullptr;
2253
2254 player->StoreItem(dest, pNewItem, true);
2255 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2256 return;
2257 }
2258 }
2259 else if (player->IsBankPos(pos))
2260 {
2261 ItemPosCountVec dest;
2262 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2263 if (msg == EQUIP_ERR_OK)
2264 {
2265 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2266
2267 // prevent crash at access and unexpected charges counting with item update queue corrupt
2269 m_targets.SetItemTarget(nullptr);
2270
2271 m_CastItem = nullptr;
2273
2274 player->BankItem(dest, pNewItem, true);
2275 return;
2276 }
2277 }
2278 else if (player->IsEquipmentPos(pos))
2279 {
2280 uint16 dest;
2281
2282 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2283
2284 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2285
2286 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2287 {
2289
2290 // prevent crash at access and unexpected charges counting with item update queue corrupt
2292 m_targets.SetItemTarget(nullptr);
2293
2294 m_CastItem = nullptr;
2296
2297 player->EquipItem(dest, pNewItem, true);
2298 player->AutoUnequipOffhandIfNeed();
2299 return;
2300 }
2301 }
2302
2303 // fail
2304 delete pNewItem;
2305}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition Item.h:86
@ ITEM_FIELD_DURABILITY
Definition UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition UpdateFields.h:70
uint8 GetSlot() const
Definition Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition Item.cpp:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:305
uint16 GetPos() const
Definition Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:306
uint8 GetBagSlot() const
Definition Item.cpp:784
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1264
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:1806
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.h:1333
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.h:1284
void UpdateEnchantmentDurations()
Definition PlayerStorage.cpp:4740
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2580
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3024
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1262
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12463
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2727
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition PlayerStorage.cpp:2038
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition PlayerQuest.cpp:1835
static bool IsBankPos(uint16 pos)
Definition Player.h:1267

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4567{
4569 return;
4570
4571 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4572
4573 uint8 slot = 0;
4574 switch (m_spellInfo->Effects[effIndex].Effect)
4575 {
4577 slot = 0;
4578 break;
4580 slot = 1;
4581 break;
4583 slot = 2;
4584 break;
4586 slot = 3;
4587 break;
4588 default:
4589 return;
4590 }
4591
4592 if (m_caster)
4593 {
4594 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4595 if (guid)
4596 {
4597 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4598 {
4599 // Recast case - null spell id to make auras not be removed on object remove from world
4600 if (m_spellInfo->Id == gameObject->GetSpellId())
4601 gameObject->SetSpellId(0);
4602 m_caster->RemoveGameObject(gameObject, true);
4603 }
4604 m_caster->m_ObjectSlot[slot].Clear();
4605 }
4606 }
4607
4608 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4609
4610 float x, y, z;
4611 // If dest location if present
4612 if (m_targets.HasDst())
4613 destTarget->GetPosition(x, y, z);
4614 // Summon in random point all other units if location present
4615 else
4617
4618 Map* map = m_caster->GetMap();
4619 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4620 {
4621 delete pGameObj;
4622 return;
4623 }
4624
4625 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4626 int32 duration = m_spellInfo->GetDuration();
4627 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4628 pGameObj->SetSpellId(m_spellInfo->Id);
4629 m_caster->AddGameObject(pGameObj);
4630
4631 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4632
4633 map->AddToMap(pGameObj, true);
4634
4635 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4636}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition ObjectDefines.h:44
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition SharedDefines.h:896
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition SharedDefines.h:893
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition SharedDefines.h:895
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition SharedDefines.h:894
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:2037

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), GameObject, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3737{
3739 return;
3740
3741 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3742
3743 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3744
3745 WorldObject* target = focusObject;
3746 if (!target)
3747 target = m_caster;
3748
3749 float x, y, z;
3750 if (m_targets.HasDst())
3751 destTarget->GetPosition(x, y, z);
3752 else
3754
3755 Map* map = target->GetMap();
3756
3757 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3758 {
3759 delete pGameObj;
3760 return;
3761 }
3762
3763 int32 duration = m_spellInfo->GetDuration();
3764
3765 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3766 pGameObj->SetSpellId(m_spellInfo->Id);
3767
3768 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3769
3770 // Wild object not have owner and check clickable by players
3771 map->AddToMap(pGameObj, true);
3772
3773 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3774 if (Player* player = m_caster->ToPlayer())
3775 if (Battleground* bg = player->GetBattleground())
3776 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3777
3778 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3779 {
3780 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3781 linkedTrap->SetSpellId(m_spellInfo->Id);
3782 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3783 }
3784}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1597
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ TEAM_HORDE
Definition SharedDefines.h:772
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2727
GameobjectTypes GetGoType() const
Definition GameObject.h:202

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GameObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3148{
3150 return;
3151
3152 if (!m_originalCaster)
3153 return;
3154
3155 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3156 int32 duration = m_spellInfo->GetDuration();
3157
3158 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3159 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3160
3161 Player* owner = m_originalCaster->ToPlayer();
3162 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3164
3165 if (!owner)
3166 {
3167 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3168 if (properties)
3169 {
3170 // Xinef: unsummon old guardian
3171 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3172 oldPet->UnSummon();
3173 SummonGuardian(effIndex, petentry, properties, 1, false);
3174 }
3175 return;
3176 }
3177
3178 Pet* OldSummon = owner->GetPet();
3179
3180 // if pet requested type already exist
3181 if (OldSummon)
3182 {
3183 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3184 {
3185 // pet in corpse state can't be summoned
3186 if (OldSummon->isDead())
3187 return;
3188
3189 ASSERT(OldSummon->GetMap() == owner->GetMap());
3190
3191 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3192
3193 float px, py, pz;
3194 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3195
3196 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3197 OldSummon->UpdateObjectVisibility();
3198
3199 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3200 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3201 // notify player
3202 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3203 owner->SendClearCooldown(itr->first, OldSummon);
3204
3205 // actually clear cooldowns
3206 OldSummon->m_CreatureSpellCooldowns.clear();
3207 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3208 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3209 {
3210 Aura const* aura = i->second->GetBase();
3211 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3212 OldSummon->RemoveAura(i);
3213 else
3214 ++i;
3215 }
3216 return;
3217 }
3218
3219 if (owner->IsPlayer())
3220 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3221 else
3222 return;
3223 }
3224
3225 float x, y, z;
3226 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3227 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3228 if (!pet)
3229 return;
3230
3231 if (m_caster->IsCreature())
3232 {
3233 if (m_caster->ToCreature()->IsTotem())
3235 else
3237 }
3238
3240
3241 // Reset cooldowns
3243 {
3244 pet->m_CreatureSpellCooldowns.clear();
3245 owner->PetSpellInitialize();
3246 }
3247
3248 // Set health to max if new pet is summoned
3249 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3250 // pet should have full health
3251 pet->SetHealth(pet->GetMaxHealth());
3252
3253 // generate new name for summon pet
3254 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3255 if (!new_name.empty())
3256 pet->SetName(new_name);
3257
3258 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3259}
@ SPELLMOD_DURATION
Definition SpellDefines.h:77
@ REACT_DEFENSIVE
Definition Unit.h:551
@ REACT_AGGRESSIVE
Definition Unit.h:552
bool CanBeSentToClient() const
Definition SpellAuras.cpp:1137
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition Creature.h:254
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition Creature.h:99
Definition TemporarySummon.h:96
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition Player.cpp:14720
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:5973
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:17363
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:19160
Powers getPowerType() const
Definition Unit.h:1093
bool isDead() const
Definition Unit.h:1750
void SetName(std::string const &newname)
Definition Object.h:526
float GetObjectSize() const
Definition Object.cpp:2789

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4220{
4221 // workaround - this effect should not use target map
4223 return;
4224
4225 if (!unitTarget)
4226 return;
4227
4228 Player* player = unitTarget->ToPlayer();
4229 if (!player)
4230 {
4231 return;
4232 }
4233
4234 // Evil Twin (ignore player summon, but hide this for summoner)
4235 // Xinef: Unit Target may be on other map!!!, Need workaround
4236 if (unitTarget->HasAura(23445))
4237 return;
4238
4239 float x, y, z;
4240 m_caster->GetPosition(x, y, z);
4241
4242 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4243
4244 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4245 data << m_caster->GetGUID(); // summoner guid
4246 data << uint32(m_caster->GetZoneId()); // summoner zone
4247 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4248 player->SendDirectMessage(&data);
4249}
#define MAX_PLAYER_SUMMON_DELAY
Definition Player.h:924
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition Player.cpp:16295
@ SMSG_SUMMON_REQUEST
Definition Opcodes.h:713

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, Player::SendDirectMessage(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6342{
6344 return;
6345
6346 if (!m_caster->IsPlayer())
6347 return;
6348
6349 if (!unitTarget)
6350 return;
6351
6352 Player* player = unitTarget->ToPlayer();
6353 if (!player)
6354 {
6355 return;
6356 }
6357
6358 float x, y, z;
6359 m_caster->GetPosition(x, y, z);
6361 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6362 data << m_caster->GetGUID();
6363 data << uint32(m_caster->GetZoneId());
6364 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6365 player->SendDirectMessage(&data);
6366}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, Player::SendDirectMessage(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2330{
2332 return;
2333
2334 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2335
2336 if (m_spellValue->MiscVal[effIndex])
2337 entry = m_spellValue->MiscVal[effIndex];
2338
2339 if (!entry)
2340 return;
2341
2342 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2343 if (!properties)
2344 {
2345 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2346 return;
2347 }
2348
2349 if (!m_originalCaster)
2350 return;
2351
2352 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2353 int32 duration = m_spellInfo->GetDuration();
2354 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2355 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2356
2357 TempSummon* summon = nullptr;
2358
2359 // determine how many units should be summoned
2360 uint32 numSummons;
2361
2362 // some spells need to summon many units, for those spells number of summons is stored in effect value
2363 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2364 // and in spell attributes, possibly we need to add a table for those)
2365 // so here's a list of MiscValueB values, which is currently most generic check
2366 switch (properties->Id)
2367 {
2368 case 64:
2369 case 61:
2370 case 1101:
2371 case 66:
2372 case 648:
2373 case 2301:
2374 case 1061:
2375 case 1261:
2376 case 629:
2377 case 181:
2378 case 715:
2379 case 1562:
2380 case 833:
2381 case 1161:
2382 case 713: // xinef, bloodworms
2383 numSummons = (damage > 0) ? damage : 1;
2384 break;
2385 default:
2386 numSummons = 1;
2387 break;
2388 }
2389
2390 switch (properties->Category)
2391 {
2395 if (properties->Flags & 512)
2396 {
2397 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2398 break;
2399 }
2400 switch (properties->Type)
2401 {
2402 case SUMMON_TYPE_PET:
2405 case SUMMON_TYPE_MINION:
2406 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2407 break;
2408 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2411 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2412 break;
2414 case SUMMON_TYPE_TOTEM:
2415 {
2416 // protection code
2417 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2418 if (!summon || !summon->IsTotem())
2419 return;
2420
2421 // Mana Tide Totem
2422 if (m_spellInfo->Id == 16190)
2424
2425 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2426 {
2427 summon->SetMaxHealth(damage);
2428 summon->SetHealth(damage);
2429 }
2430 break;
2431 }
2433 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2437 ));
2438 [[fallthrough]];
2439 case SUMMON_TYPE_JEEVES:
2440 {
2441 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2442 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2443 return;
2444
2445 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2447
2448 summon->SetImmuneToAll(true);
2450
2451 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2452 //summon->AI()->EnterEvadeMode();
2453 if (properties->Type != SUMMON_TYPE_JEEVES)
2454 {
2456 summon->GetMotionMaster()->Clear(false);
2458 }
2459 break;
2460 }
2461 default:
2462 {
2463 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2464
2465 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2466
2467 for (uint32 count = 0; count < numSummons; ++count)
2468 {
2469 Position pos;
2470 if (count == 0)
2471 pos = *destTarget;
2472 else
2473 // randomize position for multiple summons
2474 pos = m_caster->GetRandomPoint(*destTarget, radius);
2475
2476 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2477 if (!summon)
2478 continue;
2479
2480 summon->SetTempSummonType(summonType);
2481
2482 if (properties->Category == SUMMON_CATEGORY_ALLY)
2483 {
2486 }
2487
2488 ExecuteLogEffectSummonObject(effIndex, summon);
2489 }
2490 return;
2491 }
2492 }//switch
2493 break;
2495 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2496 if (m_originalCaster)
2498 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2499 break;
2501 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2502 break;
2504 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2505 // to cast a ride vehicle spell on the summoned unit.
2506 //float x, y, z;
2507 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2508 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2509 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2511
2512 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2513 if (!summon || !summon->IsVehicle())
2514 return;
2515
2516 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2518 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2519 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2520 {
2521 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2522 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2523 spellId = spellInfo->Id;
2524 }
2525
2526 // xinef: if we have small value, it indicates seat position
2527 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2528 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2529 else
2530 m_originalCaster->CastSpell(summon, spellId, true);
2531
2532 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2533 //uint32 faction = properties->Faction;
2534 //if (!faction)
2535 uint32 faction = m_originalCaster->GetFaction();
2536
2537 summon->SetFaction(faction);
2538 break;
2539 }
2540
2541 if (summon)
2542 {
2544 ExecuteLogEffectSummonObject(effIndex, summon);
2545 }
2546}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2025
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:64
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:54
constexpr float MINI_PET_SUMMON_ANGLE
Definition PetDefines.h:208
constexpr float MINI_PET_FOLLOW_ANGLE
Definition PetDefines.h:209
@ SUMMON_TYPE_VEHICLE2
Definition SharedDefines.h:3554
@ SUMMON_TYPE_LIGHTWELL
Definition SharedDefines.h:3555
@ SUMMON_TYPE_MINION
Definition SharedDefines.h:3547
@ SUMMON_TYPE_GUARDIAN
Definition SharedDefines.h:3546
@ SUMMON_TYPE_JEEVES
Definition SharedDefines.h:3556
@ SUMMON_TYPE_PET
Definition SharedDefines.h:3545
@ SUMMON_TYPE_TOTEM
Definition SharedDefines.h:3548
@ SUMMON_TYPE_VEHICLE
Definition SharedDefines.h:3553
@ SUMMON_TYPE_MINIPET
Definition SharedDefines.h:3549
@ SUMMON_TYPE_GUARDIAN2
Definition SharedDefines.h:3550
@ SUMMON_CATEGORY_VEHICLE
Definition SharedDefines.h:3537
@ SUMMON_CATEGORY_ALLY
Definition SharedDefines.h:3534
@ SUMMON_CATEGORY_WILD
Definition SharedDefines.h:3533
@ SUMMON_CATEGORY_UNK
Definition SharedDefines.h:3538
@ SPELL_AURA_CONTROL_VEHICLE
Definition SpellAuraDefines.h:299
@ UNIT_MASK_MINION
Definition UnitDefines.h:157
NPCFlags
Non Player Character flags.
Definition UnitDefines.h:317
@ REACT_PASSIVE
Definition Unit.h:550
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1523
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition Object.cpp:2165
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true, bool inheritSpeed=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition MotionMaster.cpp:446
void Clear(bool reset=true)
Definition MotionMaster.h:182
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:282
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:20289
void SetFaction(uint32 faction)
Definition Unit.cpp:10108
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:10650
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:726
void SetMaxHealth(uint32 val)
Definition Unit.cpp:15558
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:701
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:751
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:10940
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:907
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2746
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1296
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1535
uint32 npcflag
Definition CreatureData.h:199
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:229
uint32 Flags
Definition DBCStructure.h:1916
uint32 Type
Definition DBCStructure.h:1914
uint32 Id
Definition DBCStructure.h:1911

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), WorldObject::GetDistance2d(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), WorldObject::GetNearPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, m_spellValue, MAX_VEHICLE_SEATS, MINI_PET_FOLLOW_ANGLE, MINI_PET_SUMMON_ANGLE, SpellValue::MiscVal, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Position::Relocate(), Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFacingToObject(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3092{
3094 return;
3095
3096 if (m_caster->GetPetGUID())
3097 return;
3098
3099 if (!unitTarget)
3100 return;
3101
3102 if (!unitTarget->IsCreature())
3103 return;
3104
3105 Creature* creatureTarget = unitTarget->ToCreature();
3106
3107 if (creatureTarget->IsPet())
3108 return;
3109
3111 return;
3112
3113 // cast finish successfully
3114 //SendChannelUpdate(0);
3115 finish();
3116
3117 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3118 if (!pet) // in very specific state like near world end/etc.
3119 return;
3120
3121 // "kill" original creature
3122 creatureTarget->DespawnOrUnsummon();
3123
3124 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3125
3126 // prepare visual effect for levelup
3127 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3128
3129 // add to world
3130 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3131
3132 // visual effect for levelup
3133 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3134
3135 // caster have pet now
3136 m_caster->SetMinion(pet, true);
3137
3138 pet->InitTalentForLevel();
3139
3140 if (m_caster->IsPlayer())
3141 {
3144 }
3145}
@ UNIT_FIELD_LEVEL
Definition UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3288{
3290 return;
3291
3292 if (!unitTarget)
3293 return;
3294
3295 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3296 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3297 {
3298 m_caster->CastSpell(unitTarget, 67485, true);
3300 }
3301
3302 // this effect use before aura Taunt apply for prevent taunt already attacking target
3303 // for spell as marked "non effective at already attacking target"
3305 {
3307 return;
3308 }
3309
3311 {
3312 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3313 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3315 if (topThreat > myThreat)
3316 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3317
3318 //Set aggro victim to caster
3320 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3321 }
3322}
@ SPELL_AURA_MOD_TAUNT
Definition SpellAuraDefines.h:74
Definition ThreatMgr.h:48
float GetThreat() const
Definition ThreatMgr.h:62
HostileReference * getMostHated() const
Definition ThreatMgr.h:168
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition ThreatMgr.cpp:261
bool empty() const
Definition ThreatMgr.h:163
void setCurrentVictim(HostileReference *hostileRef)
Definition ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition ThreatMgr.h:275
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:14644

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1181{
1183 return;
1184
1185 if (!unitTarget || unitTarget->IsInFlight())
1186 return;
1187
1188 if (unitTarget->IsPlayer())
1189 {
1190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1191 }
1192
1193 // Pre effects
1194 switch (m_spellInfo->Id)
1195 {
1196 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1197 if (Player* target = unitTarget->ToPlayer())
1198 {
1199 uint32 mapid = destTarget->GetMapId();
1200 float x, y, z, orientation;
1201 destTarget->GetPosition(x, y, z, orientation);
1202 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1203 }
1204 return;
1205 }
1206
1207 // If not exist data for dest location - return
1208 if (!m_targets.HasDst())
1209 {
1210 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1211 return;
1212 }
1213
1214 // Init dest coordinates
1215 uint32 mapid = destTarget->GetMapId();
1216 if (mapid == MAPID_INVALID)
1217 mapid = unitTarget->GetMapId();
1218 float x, y, z, orientation;
1219 destTarget->GetPosition(x, y, z, orientation);
1220 if (!orientation && m_targets.GetUnitTarget())
1221 orientation = m_targets.GetUnitTarget()->GetOrientation();
1222 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1223
1224 if (mapid == unitTarget->GetMapId())
1225 {
1226 if (unitTarget->GetVehicleKit()) // we are vehicle!
1227 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1228 else
1229 {
1231 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1232 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1234 }
1235 }
1236 else if (unitTarget->IsPlayer())
1237 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1238 else
1239 {
1240 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1241 return;
1242 }
1243
1244 // post effects for TARGET_DEST_DB
1245 switch (m_spellInfo->Id)
1246 {
1247 // Dimensional Ripper - Everlook
1248 case 23442:
1249 {
1250 int32 r = irand(0, 119);
1251 if (r >= 70) // 7/12 success
1252 {
1253 if (r < 100) // 4/12 evil twin
1254 m_caster->CastSpell(m_caster, 23445, true);
1255 else // 1/12 fire
1256 m_caster->CastSpell(m_caster, 23449, true);
1257 }
1258 return;
1259 }
1260 // Ultrasafe Transporter: Toshley's Station
1261 case 36941:
1262 {
1263 if (roll_chance_i(50)) // 50% success
1264 {
1265 int32 rand_eff = urand(1, 7);
1266 switch (rand_eff)
1267 {
1268 case 1:
1269 // soul split - evil
1270 m_caster->CastSpell(m_caster, 36900, true);
1271 break;
1272 case 2:
1273 // soul split - good
1274 m_caster->CastSpell(m_caster, 36901, true);
1275 break;
1276 case 3:
1277 // Increase the size
1278 m_caster->CastSpell(m_caster, 36895, true);
1279 break;
1280 case 4:
1281 // Decrease the size
1282 m_caster->CastSpell(m_caster, 36893, true);
1283 break;
1284 case 5:
1285 // Transform
1286 {
1288 m_caster->CastSpell(m_caster, 36897, true);
1289 else
1290 m_caster->CastSpell(m_caster, 36899, true);
1291 break;
1292 }
1293 case 6:
1294 // chicken
1295 m_caster->CastSpell(m_caster, 36940, true);
1296 break;
1297 case 7:
1298 // evil twin
1299 m_caster->CastSpell(m_caster, 23445, true);
1300 break;
1301 }
1302 }
1303 return;
1304 }
1305 }
1306}
@ TELE_TO_SPELL
Definition Player.h:820
@ TELE_TO_GM_MODE
Definition Player.h:816
#define MAPID_INVALID
Definition Position.h:253
TeamId GetTeamId(bool original=false) const
Definition Player.h:2106
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1352
Vehicle * GetVehicleKit() const
Definition Unit.h:1879
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:565

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3662{
3664 return;
3665
3666 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3667 return;
3668
3669 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3671 return;
3672
3674}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition Unit.cpp:14683

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5907{
5909 return;
5910
5911 if (m_caster->IsPlayer())
5912 {
5913 if (Aura* aur = m_caster->GetAura(49152))
5914 aur->RecalculateAmountOfEffects();
5915 else
5916 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5917
5919 }
5920}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13140

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2829{
2831 return;
2832
2833 if (!m_caster->IsPlayer())
2834 return;
2835 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2836 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2837 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2838}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5377{
5379 return;
5380
5381 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5382
5383 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5384
5385 if (!goinfo)
5386 {
5387 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5388 return;
5389 }
5390
5391 float fx, fy, fz;
5392
5393 if (m_targets.HasDst())
5394 destTarget->GetPosition(fx, fy, fz);
5395 //FIXME: this can be better check for most objects but still hack
5396 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5397 {
5398 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5400 }
5401 else
5402 {
5403 //GO is always friendly to it's creator, get range for friends
5404 float min_dis = m_spellInfo->GetMinRange(true);
5405 float max_dis = m_spellInfo->GetMaxRange(true);
5406 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5407
5409 }
5410
5411 // Seaforium charge
5412 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5413 {
5414 fx = m_caster->GetPositionX();
5415 fy = m_caster->GetPositionY();
5416 fz = m_caster->GetPositionZ();
5417 }
5418
5419 Map* cMap = m_caster->GetMap();
5420
5421 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5422
5423 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5424 {
5425 delete pGameObj;
5426 return;
5427 }
5428
5429 int32 duration = m_spellInfo->GetDuration();
5430
5431 switch (goinfo->type)
5432 {
5434 {
5436 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5437
5438 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5439 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5440 int32 lastSec = 0;
5441 switch (urand(0, 2))
5442 {
5443 case 0:
5444 lastSec = 3;
5445 break;
5446 case 1:
5447 lastSec = 7;
5448 break;
5449 case 2:
5450 lastSec = 13;
5451 break;
5452 }
5453
5454 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5455 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5456
5457 break;
5458 }
5460 {
5461 if (m_caster->IsPlayer())
5462 {
5463 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5464 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5465 }
5466 break;
5467 }
5468 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5469 m_caster->AddGameObject(pGameObj);
5470 break;
5473 default:
5474 break;
5475 }
5476
5477 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5478
5479 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5480
5481 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5482 pGameObj->SetSpellId(m_spellInfo->Id);
5483
5484 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5485
5486 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5487 //m_caster->AddGameObject(pGameObj);
5488 //m_ObjToDel.push_back(pGameObj);
5489
5490 cMap->AddToMap(pGameObj, true);
5491
5492 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5493 {
5494 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5495 linkedTrap->SetSpellId(m_spellInfo->Id);
5496 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5497
5498 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5499 }
5500
5501 if (Player* player = m_caster->ToPlayer())
5502 {
5503 player->SetCanTeleport(true);
5504 }
5505}
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:117
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition SharedDefines.h:1587
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1588
@ UNIT_FIELD_CHANNEL_OBJECT
Definition UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:163
void AddUniqueUse(Player *player)
Definition GameObject.cpp:926
float GetMinRange(bool positive=false) const
Definition SpellInfo.cpp:2326

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GameObject, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition SharedDefines.h:937
@ TARGET_FLAG_DEST_LOCATION
Definition SpellInfo.h:52
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition SpellInfo.cpp:1038
uint32 CategoryRecoveryTime
Definition SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
786{
789 return;
790
791 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
792
794 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
796 {
797 // special cases
798 switch (triggered_spell_id)
799 {
800 // Mirror Image
801 case 58832:
802 {
803 // Glyph of Mirror Image
804 if (m_caster->HasAura(63093))
805 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
806
807 break;
808 }
809 // Demonic Empowerment -- succubus
810 case 54437:
811 {
815
816 // Cast Lesser Invisibility
817 unitTarget->CastSpell(unitTarget, 7870, true);
818 return;
819 }
820 // just skip
821 case 23770: // Sayge's Dark Fortune of *
822 // not exist, common cooldown can be implemented in scripts if need.
823 return;
824 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
825 case 29284:
826 {
827 // Brittle Armor
828 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
829 if (!spell)
830 return;
831
832 for (uint32 j = 0; j < spell->StackAmount; ++j)
833 m_caster->CastSpell(unitTarget, spell->Id, true);
834 return;
835 }
836 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
837 case 29286:
838 {
839 // Mercurial Shield
840 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
841 if (!spell)
842 return;
843
844 for (uint32 j = 0; j < spell->StackAmount; ++j)
845 m_caster->CastSpell(unitTarget, spell->Id, true);
846 return;
847 }
848 // Cloak of Shadows
849 case 35729:
850 {
853 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
854 {
855 // remove all harmful spells on you...
856 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
857
858 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
859 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
860 return;
861
862 bool dmgClassNone = false;
864 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
865 {
866 if ((iter->second->GetEffectMask() & (1 << i)) &&
867 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
870 {
871 dmgClassNone = false;
872 break;
873 }
874 dmgClassNone = true;
875 }
876
877 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
878 // ignore positive and passive auras
879 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
880 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
882 {
883 m_caster->RemoveAura(iter);
884 }
885 else
886 ++iter;
887 }
888 return;
889 }
890 }
891 }
892
893 // normal case
894 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
895 if (!spellInfo)
896 {
897 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
898 return;
899 }
900
901 SpellCastTargets targets;
903 {
904 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
905 return;
906 targets.SetUnitTarget(unitTarget);
907 }
908 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
909 {
910 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
911 return;
912
914 targets.SetDst(m_targets);
915
916 if (Unit* target = m_targets.GetUnitTarget())
917 targets.SetUnitTarget(target);
918 else
919 targets.SetUnitTarget(m_caster);
920 }
921
922 CustomSpellValues values;
923 // set basepoints for trigger with value effect
925 {
926 // maybe need to set value only when basepoints == 0?
930 }
931
932 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
933 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
934 {
935 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
936 }
937
938 // original caster guid only for GO cast
940}
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition SharedDefines.h:931
@ SPELL_EFFECT_TRIGGER_SPELL
Definition SharedDefines.h:853
@ MECHANIC_BLEED
Definition SharedDefines.h:1351
@ DISPEL_ALL
Definition SharedDefines.h:1390
@ SPELL_AURA_MOD_STALKED
Definition SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition SpellAuraDefines.h:86

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1331{
1333 return;
1334
1335 if (!unitTarget)
1336 return;
1337
1338 Player* player = unitTarget->ToPlayer();
1339 if (!player)
1340 {
1341 return;
1342 }
1343
1344 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1345
1346 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1347 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1348 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1349}
#define SPEC_MASK_ALL
Definition Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition Player.cpp:3346

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2753{
2755 return;
2756
2757 if (!unitTarget || m_caster->IsPlayer())
2758 return;
2759
2760 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2762}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:8927

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3325{
3327 return;
3328
3329 if (!unitTarget || !unitTarget->IsAlive())
3330 return;
3331
3332 // multiple weapon dmg effect workaround
3333 // execute only the last weapon damage
3334 // and handle all effects at once
3335 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3336 {
3337 switch (m_spellInfo->Effects[j].Effect)
3338 {
3343 return; // we must calculate only at last weapon effect
3344 break;
3345 }
3346 }
3347
3348 // some spell specific modifiers
3349 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3350 int32 spell_bonus = 0; // bonus specific for spell
3351 bool normalized = false;
3352
3354 {
3356 {
3357 switch (m_spellInfo->Id)
3358 {
3359 // Trial of the Champion, Black Knight, Obliterate
3360 case 67725:
3361 case 67883:
3362 {
3363 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3364 break;
3365 }
3366 }
3367 break;
3368 }
3370 {
3371 // Devastate (player ones)
3372 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3373 {
3374 m_caster->CastSpell(unitTarget, 58567, true);
3375
3376 if (Aura* aur = unitTarget->GetAura(58567))
3377 {
3378 // 58388 - Glyph of Devastate dummy aura.
3379 if (m_caster->HasAura(58388))
3380 aur->ModStackAmount(1);
3381
3382 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3383 }
3384 }
3385 break;
3386 }
3387 case SPELLFAMILY_ROGUE:
3388 {
3389 // Fan of Knives, Hemorrhage, Ghostly Strike
3390 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3391 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3392 {
3393 // Hemorrhage
3394 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3395 {
3397 }
3398 // 50% more damage with daggers
3399 if (m_caster->IsPlayer())
3400 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3401 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3402 AddPct(totalDamagePercentMod, 50.0f);
3403 }
3404 // Mutilate (for each hand)
3405 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3406 {
3407 bool found = false;
3408 // fast check
3410 found = true;
3411 // full aura scan
3412 else
3413 {
3415 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3416 {
3417 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3418 {
3419 found = true;
3420 break;
3421 }
3422 }
3423 }
3424
3425 if (found)
3426 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3427 }
3428 break;
3429 }
3431 {
3432 switch (m_spellInfo->Id)
3433 {
3434 case 20467: // Seal of Command Unleashed
3435 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3437 break;
3438 case 53385: // Divine Storm deals normalized damage
3439 normalized = true;
3440 break;
3441 default:
3442 break;
3443 }
3444 break;
3445 }
3446 case SPELLFAMILY_SHAMAN:
3447 {
3448 // Skyshatter Harness item set bonus
3449 // Stormstrike
3450 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3451 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3452 // Lava lash damage increased by Flametongue weapon
3454 AddPct(totalDamagePercentMod, 25.0f);
3455 break;
3456 }
3457 case SPELLFAMILY_DRUID:
3458 {
3459 // Mangle (Cat): CP
3460 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3461 {
3463 }
3464 // Shred, Maul - Rend and Tear
3466 {
3467 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3468 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3469 }
3470 break;
3471 }
3472 case SPELLFAMILY_HUNTER:
3473 {
3474 // Kill Shot
3475 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3476 {
3477 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3478 }
3479 break;
3480 }
3482 {
3483 // Plague Strike
3484 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3485 {
3486 // Glyph of Plague Strike
3487 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3488 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3489 break;
3490 }
3491 // Blood Strike
3492 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3493 {
3494 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3495 //Death Knight T8 Melee 4P Bonus
3496 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3497 AddPct(disease_amt, aurEff->GetAmount());
3498
3499 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3500
3501 // Glyph of Blood Strike
3502 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3504 AddPct(totalDamagePercentMod, 20.0f);
3505 break;
3506 }
3507 // Death Strike
3508 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3509 {
3510 // Glyph of Death Strike
3511 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3512 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3513 AddPct(totalDamagePercentMod, runic);
3514 break;
3515 }
3516 // Obliterate (12.5% more damage per disease)
3517 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3518 {
3519 bool consumeDiseases = true;
3520 // Annihilation
3522 // Do not consume diseases if roll sucesses
3523 if (roll_chance_i(aurEff->GetAmount()))
3524 consumeDiseases = false;
3525
3526 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3527 //Death Knight T8 Melee 4P Bonus
3528 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3529 AddPct(disease_amt, aurEff->GetAmount());
3530
3531 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3532 break;
3533 }
3534 // Blood-Caked Strike - Blood-Caked Blade
3535 if (m_spellInfo->SpellIconID == 1736)
3536 {
3537 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
3538 break;
3539 }
3540 // Heart Strike
3541 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3542 {
3543 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3544 //Death Knight T8 Melee 4P Bonus
3545 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3546 AddPct(disease_amt, aurEff->GetAmount());
3547
3548 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3549 break;
3550 }
3551 // Rune Strike
3552 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3553 {
3554 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3555 }
3556
3557 break;
3558 }
3559 }
3560
3561 float weaponDamagePercentMod = 100.0f;
3562 int32 fixed_bonus = 0;
3563
3564 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3565 {
3566 switch (m_spellInfo->Effects[j].Effect)
3567 {
3570 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3571 break;
3573 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3574 normalized = true;
3575 break;
3577 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3578 break;
3579 default:
3580 break; // not weapon damage effect, just skip
3581 }
3582 }
3583
3584 bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
3585 if (isPhysical && (fixed_bonus || spell_bonus))
3586 {
3587 UnitMods unitMod;
3588 switch (m_attackType)
3589 {
3590 default:
3591 case BASE_ATTACK:
3592 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3593 break;
3594 case OFF_ATTACK:
3595 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3596 break;
3597 case RANGED_ATTACK:
3598 unitMod = UNIT_MOD_DAMAGE_RANGED;
3599 break;
3600 }
3601 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3602 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3603 spell_bonus = int32(spell_bonus * weapon_total_pct);
3604 }
3605
3606 int32 weaponDamage = 0;
3607 // Dancing Rune Weapon
3608 if (m_caster->GetEntry() == 27893)
3609 {
3610 if (Unit* owner = m_caster->GetOwner())
3611 weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
3612 }
3613 else
3614 {
3615 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, isPhysical);
3616 }
3617
3618 // Sequence is important
3619 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3620 {
3621 // We assume that a spell have at most one fixed_bonus
3622 // and at most one weaponDamagePercentMod
3623 switch (m_spellInfo->Effects[j].Effect)
3624 {
3628 weaponDamage += fixed_bonus;
3629 break;
3631 ApplyPct(weaponDamage, weaponDamagePercentMod);
3632 default:
3633 break; // not weapon damage effect, just skip
3634 }
3635 }
3636
3637 weaponDamage += spell_bonus;
3638 ApplyPct(weaponDamage, totalDamagePercentMod);
3639
3640 // prevent negative damage
3641 uint32 eff_damage(std::max(weaponDamage, 0));
3642
3643 // Add melee damage bonuses (also check for negative)
3646
3647 // Meteor like spells (divided damage to targets)
3649 {
3650 uint32 count = 0;
3651 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3652 if (ihit->effectMask & (1 << effIndex))
3653 ++count;
3654
3655 eff_damage /= count; // divide to all targets
3656 }
3657
3658 m_damage += eff_damage;
3659}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition ItemTemplate.h:359
@ POWER_RUNIC_POWER
Definition SharedDefines.h:286
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition SharedDefines.h:910
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition SharedDefines.h:820
@ AURA_STATE_DEADLY_POISON
Definition SharedDefines.h:1319
@ AURA_STATE_BLEEDING
Definition SharedDefines.h:1321
@ DISPEL_POISON
Definition SharedDefines.h:1387
UnitMods
Definition Unit.h:144
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:168
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:169
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:167
@ TOTAL_PCT
Definition Unit.h:131
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13356
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition Unit.cpp:5913
bool HasDecreaseSpeedAura() const
Definition Unit.h:1781
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition Unit.cpp:5619
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition Unit.cpp:15318
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition Unit.cpp:3022
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition Unit.cpp:12015
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:13154

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasDecreaseSpeedAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_DUMMY, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5104{
5105 InitEffectExecuteData(effIndex);
5106 *m_effectExecuteData[effIndex] << uint32(entry);
5107}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8463

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5110{
5111 InitEffectExecuteData(effIndex);
5112 *m_effectExecuteData[effIndex] << uint32(entry);
5113}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5090{
5091 InitEffectExecuteData(effIndex);
5092 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5093 *m_effectExecuteData[effIndex] << int32(itemId);
5094 *m_effectExecuteData[effIndex] << int32(slot);
5095}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5076{
5077 InitEffectExecuteData(effIndex);
5078 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5079 *m_effectExecuteData[effIndex] << uint32(attCount);
5080}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5083{
5084 InitEffectExecuteData(effIndex);
5085 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5086 *m_effectExecuteData[effIndex] << uint32(spellId);
5087}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5098{
5099 InitEffectExecuteData(effIndex);
5100 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5101}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5128{
5129 InitEffectExecuteData(effIndex);
5130 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5131}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5067{
5068 InitEffectExecuteData(effIndex);
5069 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5070 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5071 *m_effectExecuteData[effIndex] << uint32(PowerType);
5072 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5073}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5122{
5123 InitEffectExecuteData(effIndex);
5124 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5125}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4437{
4438 if (!m_caster)
4439 return;
4440
4442 return;
4444
4445 if (m_spellInfo->IsChanneled())
4447
4450
4451 // Unsummon summon as possessed creatures on spell cancel
4453 {
4454 if (Unit* charm = m_caster->GetCharm())
4455 if (charm->IsCreature()
4456 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4457 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4458 ((Puppet*)charm)->UnSummon();
4459 }
4460
4461 if (Creature* creatureCaster = m_caster->ToCreature())
4462 creatureCaster->ReleaseFocus(this);
4463
4464 if (ok)
4465 {
4468 }
4469 else
4470 {
4471 if (m_caster->IsPlayer())
4472 {
4473 // Xinef: Restore spell mods in case of fail cast
4475
4476 // Xinef: Reset cooldown event in case of fail cast
4479
4480 // Rogue fix: Remove Cold Blood if Mutilate off-hand failed
4481 if (m_spellInfo->Id == 27576) // Mutilate, off-hand
4482 if (m_caster->HasAura(14177))
4483 m_caster->RemoveAura(14177);
4484 }
4485 return;
4486 }
4487
4488 // pussywizard:
4491
4493 {
4494 // Unsummon statue
4496 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4497 if (spellInfo && spellInfo->SpellIconID == 2056)
4498 {
4499 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4501 return;
4502 }
4503 }
4504
4505 // potions disabled by client, send event "not in combat" if need
4508
4509 // Take mods after trigger spell (needed for 14177 to affect 48664)
4510 // mods are taken only on succesfull cast and independantly from targets of the spell
4511 if (Player* player = m_caster->GetSpellModOwner())
4512 player->RemoveSpellMods(this);
4513
4514 // xinef: clear reactive auras states after spell cast
4517
4518 // Stop Attack for some spells
4521}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:159
@ AURA_STATE_DEFENSE
Definition SharedDefines.h:1303
@ AURA_STATE_HUNTER_PARRY
Definition SharedDefines.h:1309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition UnitDefines.h:162
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition Map.cpp:2514
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1546
Definition TemporarySummon.h:115
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:14583
void UpdateInterruptMask()
Definition Unit.cpp:768
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:10574

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), JustDied, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Unit::RemoveAura(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8459{
8461}
void SendLogExecute()
Definition Spell.cpp:5032

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

◆ GetCastTimeRemaining()

int32 Spell::GetCastTimeRemaining ( )
inline
562{ return m_timer;}

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8922{
8923 std::stringstream sstr;
8924 sstr << std::boolalpha
8925 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8926 << " State: " << getState();
8927 return sstr.str();
8928}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
574{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
577{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
588{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2045{
2046 // this function selects which containers need to be searched for spell target
2048
2049 // filter searchers based on searched object type
2050 switch (objType)
2051 {
2058 break;
2062 break;
2063 default:
2064 break;
2065 }
2067 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2071 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2073 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2074
2075 if (condList)
2076 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2077 return retMask;
2078}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:71
@ SPELL_ATTR5_NOT_ON_PLAYER
Definition SharedDefines.h:585
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition SharedDefines.h:467
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition SharedDefines.h:516
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition SharedDefines.h:512
@ TARGET_OBJECT_TYPE_CORPSE
Definition SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition SpellInfo.h:104

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, SPELL_ATTR5_NOT_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
595{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
603{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4125{
4126 if (!UpdatePointers())
4127 {
4128 // finish the spell if UpdatePointers() returned false, something wrong happened there
4129 finish(false);
4130 return 0;
4131 }
4132
4133 Player* modOwner = m_caster->GetSpellModOwner();
4134 if (modOwner)
4135 modOwner->SetSpellModTakingSpell(this, true);
4136
4137 uint64 next_time = m_delayTrajectory;
4138
4140
4141 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4142 {
4144 m_immediateHandled = true;
4146 next_time = 0;
4147 }
4148
4149 bool single_missile = (m_targets.HasDst());
4150
4151 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4152 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4153 {
4154 if (ihit->processed == false)
4155 {
4156 if (single_missile || ihit->timeDelay <= t_offset)
4157 {
4158 ihit->timeDelay = t_offset;
4159 DoAllEffectOnTarget(&(*ihit));
4160 }
4161 else if (next_time == 0 || ihit->timeDelay < next_time)
4162 next_time = ihit->timeDelay;
4163 }
4164 }
4165
4166 // now recheck gameobject targeting correctness
4167 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4168 {
4169 if (ighit->processed == false)
4170 {
4171 if (single_missile || ighit->timeDelay <= t_offset)
4172 DoAllEffectOnTarget(&(*ighit));
4173 else if (next_time == 0 || ighit->timeDelay < next_time)
4174 next_time = ighit->timeDelay;
4175 }
4176 }
4177
4179
4180 if (modOwner)
4181 modOwner->SetSpellModTakingSpell(this, false);
4182
4183 // All targets passed - need finish phase
4184 if (next_time == 0)
4185 {
4186 // spell is finished, perform some last features of the spell here
4188
4189 finish(true); // successfully finish spell cast
4190
4191 // return zero, spell is finished now
4192 return 0;
4193 }
4194 else
4195 {
4196 // spell is unfinished, return next execution time
4197 return next_time;
4198 }
4199}
void _handle_finish_phase()
Definition Spell.cpp:4229
void PrepareTargetProcessing()
Definition Spell.cpp:8453
void _handle_immediate_phase()
Definition Spell.cpp:4201
void FinishTargetProcessing()
Definition Spell.cpp:8458

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4065{
4066 // start channeling if applicable
4067 if (m_spellInfo->IsChanneled())
4068 {
4069 int32 duration = m_spellInfo->GetDuration();
4071 duration = -1;
4072
4073 if (duration > 0)
4074 {
4075 // First mod_duration then haste - see Missile Barrage
4076 // Apply duration mod
4077 if (Player* modOwner = m_caster->GetSpellModOwner())
4078 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4079
4080 // Apply haste mods
4082 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4083
4086 m_channeledDuration = duration;
4087 SendChannelStart(duration);
4088 }
4089 else if (duration == -1)
4090 {
4093 SendChannelStart(duration);
4094 }
4095 }
4096
4098
4099 // process immediate effects (items, ground, etc.) also initialize some variables
4101
4102 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4103 DoAllEffectOnTarget(&(*ihit));
4104
4105 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4106 DoAllEffectOnTarget(&(*ihit));
4107
4109
4110 // spell is finished, perform some last features of the spell here
4112
4113 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4114 TakeCastItem();
4115
4116 // handle ammo consumption for Hunter's volley spell
4118 TakeAmmo();
4119
4121 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4122}
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5165
void TakeAmmo()
Definition Spell.cpp:5338
void AddInterruptMask(uint32 mask)
Definition Unit.h:1563

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5588{
5590 return;
5591
5592 effectHandleMode = mode;
5593 unitTarget = pUnitTarget;
5594 itemTarget = pItemTarget;
5595 gameObjTarget = pGOTarget;
5597
5598 uint8 eff = m_spellInfo->Effects[i].Effect;
5599
5600 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5601
5602 // we do not need DamageMultiplier here.
5603 damage = CalculateSpellDamage(i, nullptr);
5604
5605 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5606
5607 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5608 {
5609 (this->*SpellEffects[eff])((SpellEffIndex)i);
5610 }
5611}
SpellEffIndex
Definition SharedDefines.h:30
SpellEffects
Definition SharedDefines.h:789
@ TOTAL_SPELL_EFFECTS
Definition SharedDefines.h:954
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition Spell.cpp:8572
WorldLocation _position
Definition Spell.h:113

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8212{
8213 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8214 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8215 {
8216 // don't do anything for empty effect
8217 if (!m_spellInfo->Effects[i].IsEffect())
8218 continue;
8219
8220 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8221 }
8222
8223 float multiplier[MAX_SPELL_EFFECTS];
8224 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8225 if (m_applyMultiplierMask & (1 << i))
8226 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8227
8230 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8231 {
8232 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8233 usesAmmo = false;
8234 }
8235
8237
8238 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8239 {
8240 TargetInfo& target = *ihit;
8241
8242 uint32 mask = target.effectMask;
8243 if (!mask)
8244 continue;
8245
8246 // do not consume ammo anymore for Hunter's volley spell
8248 usesAmmo = false;
8249
8250 if (usesAmmo)
8251 {
8252 bool ammoTaken = false;
8253 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8254 {
8255 if (!(mask & 1 << i))
8256 continue;
8257 switch (m_spellInfo->Effects[i].Effect)
8258 {
8264 ammoTaken = true;
8265 TakeAmmo();
8266 }
8267 if (ammoTaken)
8268 break;
8269 }
8270 }
8271
8272 DoAllEffectOnLaunchTarget(target, multiplier);
8273 }
8274
8276}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition SharedDefines.h:791
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition SpellInfo.h:184
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition Spell.cpp:8278

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5541{
5542 if (m_UniqueTargetInfo.empty())
5543 return;
5544
5546 return;
5547
5548 float threat = 0.0f;
5549 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5550 {
5551 if (threatEntry->apPctMod != 0.0f)
5552 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5553
5554 threat += threatEntry->flatMod;
5555 }
5557 threat += m_spellInfo->SpellLevel;
5558
5559 // past this point only multiplicative effects occur
5560 if (threat == 0.0f)
5561 return;
5562
5563 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5564 threat /= m_UniqueTargetInfo.size();
5565
5566 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5567 {
5568 float threatToAdd = threat;
5569 if (ihit->missCondition != SPELL_MISS_NONE)
5570 threatToAdd = 0.0f;
5571
5572 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5573 if (!target)
5574 continue;
5575
5576 bool IsFriendly = m_caster->IsFriendlyTo(target);
5577 // positive spells distribute threat among all units that are in combat with target, like healing
5579 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5580 // for negative spells threat gets distributed among affected targets
5581 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5582 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5583 }
5584 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5585}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition boss_chess_event.cpp:180
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:2843
Definition SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8082{
8083 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8084 if (itr->effectMask & (1 << effect))
8085 return true;
8086
8087 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8088 if (itr->effectMask & (1 << effect))
8089 return true;
8090
8091 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8092 if (itr->effectMask & (1 << effect))
8093 return true;
8094
8095 return false;
8096}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8464{
8465 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8466 if (!m_effectExecuteData[effIndex])
8467 {
8468 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8469 // first dword - target counter
8470 *m_effectExecuteData[effIndex] << uint32(1);
8471 }
8472 else
8473 {
8474 // increase target counter by one
8475 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8476 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8477 }
8478}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
720{
721 m_targets = targets;
722 // this function tries to correct spell explicit targets for spell
723 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
724 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
725 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
726
727 if (WorldObject* target = m_targets.GetObjectTarget())
728 {
729 // check if object target is valid with needed target flags
730 // for unit case allow corpse target mask because player with not released corpse is a unit target
731 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
732 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
733 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
735 }
736 else
737 {
738 // try to select correct unit target if not provided by client or by serverside cast
739 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
740 {
741 Unit* unit = nullptr;
742 // try to use player selection as a target
743 if (Player* playerCaster = m_caster->ToPlayer())
744 {
745 // selection has to be found and to be valid target for the spell
746 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
748 unit = selectedUnit;
749 }
750 // try to use attacked unit as a target
751 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
752 unit = m_caster->GetVictim();
753
754 // didn't find anything - let's use self as target
755 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
756 unit = m_caster;
757
759 }
760 }
761
762 // check if spell needs dst target
763 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
764 {
765 // and target isn't set
766 if (!m_targets.HasDst())
767 {
768 // try to use unit target if provided
769 if (WorldObject* target = targets.GetObjectTarget())
770 m_targets.SetDst(*target);
771 // or use self if not available
772 else
774 }
775 }
776 else
778
779 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
780 {
781 if (!targets.HasSrc())
783 }
784 else
786}
@ TARGET_FLAG_UNIT_RAID
Definition SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition SpellInfo.h:49
void RemoveDst()
Definition Spell.cpp:448
void RemoveSrc()
Definition Spell.cpp:391

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8056{
8059 {
8060 return false;
8061 }
8062
8064 {
8065 return false;
8066 }
8067
8068 return true;
8069}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition SharedDefines.h:640

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
641 {
642 if (m_delayAtDamageCount >= 2)
643 return true;
644
646 return false;
647 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
572{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8204{
8205 if (target->IsAlive())
8207
8209}
bool IsRequiringDeadTarget() const
Definition SpellInfo.cpp:1222
bool IsAllowingDeadTarget() const
Definition SpellInfo.cpp:1227

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8487{
8488 if (_scriptsLoaded)
8489 return;
8490 _scriptsLoaded = true;
8491 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8492 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8493 {
8494 if (!(*itr)->_Load(this))
8495 {
8496 std::list<SpellScript*>::iterator bitr = itr;
8497 ++itr;
8498 delete (*bitr);
8499 m_loadedScripts.erase(bitr);
8500 continue;
8501 }
8502 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8503 (*itr)->Register();
8504 ++itr;
8505 }
8506}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8892{
8893 if (!m_caster || !m_caster->IsInWorld())
8894 return;
8895
8896 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8897
8898 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8899 // can succeed with a lockId of 0
8900 if (m_spellInfo->Id == 21651)
8901 {
8902 if (GameObject* go = m_targets.GetGOTarget())
8903 {
8904 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8905 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8906 {
8907 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8908 visual->prepare(&m_targets);
8909 }
8910 }
8911 }
8912}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2619
@ TRIGGERED_NONE
Definition SpellDefines.h:133

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3413{
3414 if (m_CastItem)
3415 {
3417 }
3418 else
3419 {
3421 }
3422
3423 InitExplicitTargets(*targets);
3424
3425 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3426 {
3427 finish(false);
3428 return SPELL_FAILED_UNKNOWN;
3429 }
3430
3431 // Fill aura scaling information
3433 {
3434 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3435 {
3436 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3439 {
3440 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3442 {
3443 m_auraScaleMask |= (1 << i);
3444 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3445 {
3446 m_auraScaleMask = 0;
3447 break;
3448 }
3449 }
3450 }
3451 }
3452 }
3453
3455
3456 if (triggeredByAura)
3457 {
3458 m_triggeredByAuraSpell.Init(triggeredByAura);
3459 }
3460
3461 // create and add update event for this spell
3462 _spellEvent = new SpellEvent(this);
3464
3465 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3466 {
3468 finish(false);
3470 }
3471
3472 //Prevent casting at cast another spell (ServerSide check)
3474 {
3476 finish(false);
3478 }
3479
3480 LoadScripts();
3481
3482 OnSpellLaunch();
3483
3485
3486 // Set combo point requirement
3488 m_needComboPoints = false;
3489
3490 SpellCastResult result = CheckCast(true);
3491 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3492 {
3493 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3494 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3495 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3496 // a possible alternative sollution for those would be validating aura target on unit state change
3497 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3498 {
3500 triggeredByAura->GetBase()->SetDuration(0);
3501 }
3502
3503 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3505 {
3506 SendCastResult(result);
3507
3508 finish(false);
3509 return result;
3510 }
3511 }
3512
3513 // Prepare data for triggers
3514 prepareDataForTriggerSystem(triggeredByAura);
3515
3516 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3518
3519 if (m_caster->IsPlayer())
3521 m_casttime = 0;
3522
3523 // don't allow channeled spells / spells with cast time to be casted while moving
3524 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3526 {
3527 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3529 {
3531 finish(false);
3532 return SPELL_FAILED_MOVING;
3533 }
3534 }
3535
3536 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3537 if (m_CastItem)
3538 {
3539 bool selectTargets = false;
3540 bool nearbyDest = false;
3541
3542 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3543 {
3544 if (!m_spellInfo->Effects[i].IsEffect())
3545 continue;
3546
3547 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3548 {
3549 selectTargets = false;
3550 break;
3551 }
3552
3553 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3554 {
3555 nearbyDest = true;
3556 }
3557
3558 // xinef: by default set it to false, and to true if any valid target is found
3559 selectTargets = true;
3560 }
3561
3562 if (selectTargets)
3563 {
3565 _spellTargetsSelected = true;
3566 bool spellFailed = false;
3567
3568 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3569 {
3570 // no valid nearby target unit or game object found; check if nearby destination type
3571 if (nearbyDest)
3572 {
3573 if (!m_targets.HasDst())
3574 {
3575 // no valid target destination
3576 spellFailed = true;
3577 }
3578 }
3579 else
3580 {
3581 spellFailed = true;
3582 }
3583 }
3584
3585 if (spellFailed)
3586 {
3588 finish(false);
3590 }
3591 }
3592 }
3593
3594 // set timer base at cast time
3595 ReSetTimer();
3596
3597 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3598
3600 {
3602 }
3603
3604 //Containers for channeled spells have to be set
3605 //TODO:Apply this to all casted spells if needed
3606 // Why check duration? 29350: channelled triggers channelled
3608 cast(true);
3609 else
3610 {
3611 // stealth must be removed at cast starting (at show channel bar)
3612 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3614 {
3615 // Farsight spells exception
3616 uint32 exceptSpellId = 0;
3618 {
3619 exceptSpellId = m_spellInfo->Id;
3620 }
3621
3624 }
3625
3628
3629 // set target for proper facing
3631 {
3634 {
3635 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3636 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3638 }
3639 }
3640
3641 //item: first cast may destroy item and second cast causes crash
3642 // xinef: removed !m_spellInfo->StartRecoveryTime
3643 // second los check failed in events
3644 // xinef: removed itemguid check, currently there is no such item in database
3646 cast(true);
3647
3650 }
3651
3652 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3653
3654 return SPELL_CAST_OK;
3655}
@ CHEAT_CASTTIME
Definition Player.h:995
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition SharedDefines.h:824
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition SharedDefines.h:854
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition SharedDefines.h:420
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition SpellDefines.h:138
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition SpellDefines.h:142
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition SpellDefines.h:140
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition SpellDefines.h:26
@ TARGET_SELECT_CATEGORY_NEARBY
Definition SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition SpellInfo.h:100
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition Creature.cpp:3445
Definition Spell.cpp:519
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1261
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2357
uint32 Attributes
Definition SpellInfo.h:324
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1271
void LoadScripts()
Definition Spell.cpp:8486
void cast(bool skipCheck=false)
Definition Spell.cpp:3730
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2204
void SendSpellStart()
Definition Spell.cpp:4676
void TriggerGlobalCooldown()
Definition Spell.cpp:8830
void OnSpellLaunch()
Definition Spell.cpp:8891
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7891
void ReSetTimer()
Definition Spell.h:561
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:719
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4014
bool IsSitState() const
Definition Unit.cpp:16729
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:8914

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEventAtOffset(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, WorldObject::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), sDisableMgr, SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2205{
2206 //==========================================================================================
2207 // Now fill data for trigger system, need know:
2208 // can spell trigger another or not (m_canTrigger)
2209 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2210 //==========================================================================================
2211
2213 // Get data for type of attack and fill base info for trigger
2214 switch (m_spellInfo->DmgClass)
2215 {
2218 if (m_attackType == OFF_ATTACK)
2220 else
2223 break;
2225 // Auto attack
2227 {
2230 }
2231 else // Ranged spell attack
2232 {
2235 }
2236 break;
2237 default:
2240 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2241 {
2244 }
2245 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2246 // Because spell positivity is dependant on target
2247 }
2249
2250 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2252 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2253 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2254 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2255 {
2257 }
2258
2259 /* Effects which are result of aura proc from triggered spell cannot proc
2260 to prevent chain proc of these spells */
2261
2262 // Hellfire Effect - trigger as DOT
2264 {
2267 }
2268
2269 // Ranged autorepeat attack is set as triggered spell - ignore it
2271 {
2278 }
2279 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2282}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition SharedDefines.h:497
@ SPELL_ATTR3_NOT_A_PROC
Definition SharedDefines.h:513
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition SpellDefines.h:148
@ PROC_EX_NONE
Definition SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition SpellMgr.h:141

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8567{
8568 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8569 (*scritr)->_InitHit();
8570}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8741{
8744 {
8745 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8746 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8748 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8749 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8751 }
8752
8755 {
8757 {
8758 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8759 {
8761 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8762 {
8763 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8764 {
8765 m_preCastSpell = 26017;
8766 break;
8767 }
8768 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8769 m_preCastSpell = 67;
8770 }
8771 }
8772 break;
8773 }
8774 case SPELLFAMILY_DRUID:
8775 {
8776 // Faerie Fire (Feral)
8778 m_preCastSpell = 60089;
8779
8780 break;
8781 }
8782 }
8783
8784 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8785 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8786 // and to correctly calculate proc chance when combopoints are present
8788 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8789 {
8790 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8791 continue;
8792 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8793 uint32 auraSpellIdx = (*i)->GetEffIndex();
8794 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8795 {
8796 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8797 // this possibly needs fixing
8798 int32 auraBaseAmount = (*i)->GetBaseAmount();
8799 // proc chance is stored in effect amount
8800 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8801 // build trigger and add to the list
8802 HitTriggerSpell spellTriggerInfo;
8803 spellTriggerInfo.triggeredSpell = spellInfo;
8804 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8805 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8806 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8807 m_hitTriggerSpells.push_back(spellTriggerInfo);
8808 }
8809 }
8810}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition UnitDefines.h:77
@ FORM_BEAR
Definition UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
923{
926}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:901
uint64 GetDelayStart() const
Definition Spell.h:574

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, WorldObject::m_Events, and EventProcessor::ModifyEventTime().

Referenced by WorldSession::HandleUpdateProjectilePosition().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
561{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2102{
2103 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2104 if (!containerTypeMask)
2105 return;
2106 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2107 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2108 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2109}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2044
Definition GridNotifiers.h:230

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2112{
2113 // max dist for jump target selection
2114 float jumpRadius = 0.0f;
2115 switch (m_spellInfo->DmgClass)
2116 {
2118 // 7.5y for multi shot
2119 jumpRadius = 7.5f;
2120 break;
2122 // 5y for swipe, cleave and similar
2123 jumpRadius = 5.0f;
2124 break;
2127 // 12.5y for chain heal spell since 3.2 patch
2128 if (isChainHeal)
2129 jumpRadius = 12.5f;
2130 // 10y as default for magic chain spells
2131 else
2132 jumpRadius = 10.0f;
2133 break;
2134 }
2135
2136 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2140
2141 // max dist which spell can reach
2142 float searchRadius = jumpRadius;
2143 if (isBouncingFar)
2144 searchRadius *= chainTargets;
2145
2147 std::list<WorldObject*> tempTargets;
2148 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList);
2149 tempTargets.remove(target);
2150
2151 // remove targets which are always invalid for chain spells
2152 // for some spells allow only chain targets in front of caster (swipe for example)
2153 if (!isBouncingFar)
2154 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2155
2156 while (chainTargets)
2157 {
2158 // try to get unit for next chain jump
2159 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2160 // get unit with highest hp deficit in dist
2161 if (isChainHeal)
2162 {
2163 uint32 maxHPDeficit = 0;
2164 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2165 {
2166 if (Unit* unit = (*itr)->ToUnit())
2167 {
2168 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2169 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2170 {
2171 foundItr = itr;
2172 maxHPDeficit = deficit;
2173 }
2174 }
2175 }
2176 }
2177 // get closest object
2178 else
2179 {
2180 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2181 {
2182 if (foundItr == tempTargets.end())
2183 {
2184 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2185 foundItr = itr;
2186 }
2187 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2188 foundItr = itr;
2189 }
2190 }
2191 // not found any valid target - chain ends
2192 if (foundItr == tempTargets.end())
2193 break;
2194
2196 chainSource = *foundItr;
2197
2198 targets.push_back(*foundItr);
2199 tempTargets.erase(foundItr);
2200 --chainTargets;
2201 }
2202}
@ SPELL_ATTR2_CHAIN_FROM_CASTER
Definition SharedDefines.h:479
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition SharedDefines.h:559
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition Spell.cpp:2101
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1414
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1349

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR2_CHAIN_FROM_CASTER, SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2090{
2091 WorldObject* target = nullptr;
2092 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2093 if (!containerTypeMask)
2094 return nullptr;
2095 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2097 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2098 return target;
2099}
Definition GridNotifiers.h:210

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2082{
2083 if (!containerMask)
2084 return;
2085
2086 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2087}

References WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), and Cell::VisitObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
929{
930 if (!targetType.GetTarget())
931 return;
932
933 uint32 effectMask = 1 << effIndex;
934 // set the same target list for all effects
935 // some spells appear to need this, however this requires more research
936 switch (targetType.GetSelectionCategory())
937 {
941 {
942 // targets for effect already selected
943 if (effectMask & processedEffectMask)
944 {
945 return;
946 }
947
948 auto const& effects = GetSpellInfo()->Effects;
949
950 // choose which targets we can select at once
951 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
952 {
953 if (effects[j].IsEffect() &&
954 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
955 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
956 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
957 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
959 {
960 effectMask |= 1 << j;
961 }
962 }
963 processedEffectMask |= effectMask;
964 break;
965 }
966 default:
967 break;
968 }
969
970 switch (targetType.GetSelectionCategory())
971 {
973 SelectImplicitChannelTargets(effIndex, targetType);
974 break;
976 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
977 break;
979 SelectImplicitConeTargets(effIndex, targetType, effectMask);
980 break;
982 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
983 break;
985 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
986 CheckDst();
987
988 SelectImplicitTrajTargets(effIndex, targetType);
989 break;
991 switch (targetType.GetObjectType())
992 {
994 switch (targetType.GetReferenceType())
995 {
998 break;
999 default:
1000 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1001 break;
1002 }
1003 break;
1005 switch (targetType.GetReferenceType())
1006 {
1008 SelectImplicitCasterDestTargets(effIndex, targetType);
1009 break;
1011 SelectImplicitTargetDestTargets(effIndex, targetType);
1012 break;
1014 SelectImplicitDestDestTargets(effIndex, targetType);
1015 break;
1016 default:
1017 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1018 break;
1019 }
1020 break;
1021 default:
1022 switch (targetType.GetReferenceType())
1023 {
1025 SelectImplicitCasterObjectTargets(effIndex, targetType);
1026 break;
1028 SelectImplicitTargetObjectTargets(effIndex, targetType);
1029 break;
1030 default:
1031 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1032 break;
1033 }
1034 break;
1035 }
1036 break;
1038 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1039 break;
1040 default:
1041 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1042 break;
1043 }
1044}
@ TARGET_SELECT_CATEGORY_CONE
Definition SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1732
void CheckDst()
Definition Spell.h:503
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1878
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1216
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1695
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1266
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1046
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1815
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1768
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1102
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8701
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1348

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
1962{
1963 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
1965 switch (m_spellInfo->Effects[effIndex].Effect)
1966 {
1970 {
1972
1974
1975 if (target && target->ToPlayer())
1976 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
1977 }
1978 return;
1979 default:
1980 break;
1981 }
1982
1983 // select spell implicit targets based on effect type
1984 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1985 return;
1986
1987 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
1988
1989 if (!targetMask)
1990 return;
1991
1992 WorldObject* target = nullptr;
1993
1994 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
1995 {
1996 // add explicit object target or self to the target map
1998 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2000 {
2002 target = unitTarget;
2003 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2004 {
2005 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2006 {
2008 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2009 target = owner;
2010 }
2011 }
2012 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2013 target = m_caster;
2014 }
2015 if (targetMask & TARGET_FLAG_ITEM_MASK)
2016 {
2018 AddItemTarget(itemTarget, 1 << effIndex);
2019 return;
2020 }
2021 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2022 target = m_targets.GetGOTarget();
2023 break;
2024 // add self to the target map
2026 if (targetMask & TARGET_FLAG_UNIT_MASK)
2027 target = m_caster;
2028 break;
2029 default:
2030 break;
2031 }
2032
2034
2035 if (target)
2036 {
2037 if (target->ToUnit())
2038 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2039 else if (target->ToGameObject())
2040 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2041 }
2042}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:72
GameObject * ToGameObject()
Definition Object.h:214
Corpse * GetCorpseTarget() const
Definition Spell.cpp:294
Definition SpellInfo.h:217
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2426
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2293
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2488
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8673

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
789{
790 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
791 if (Unit* target = m_targets.GetUnitTarget())
792 {
793 // check for explicit target redirection, for Grounding Totem for example
797 {
798 Unit* redirect;
799 switch (m_spellInfo->DmgClass)
800 {
803 break;
807 break;
808 default:
809 redirect = nullptr;
810 break;
811 }
812 if (redirect && (redirect != target))
813 {
814 m_targets.SetUnitTarget(redirect);
816 }
817 }
818 }
819}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:11138
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:11100

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1267{
1268 Unit* referer = nullptr;
1269 switch (targetType.GetReferenceType())
1270 {
1274 referer = m_caster;
1275 break;
1277 referer = m_targets.GetUnitTarget();
1278 break;
1280 {
1281 // find last added target for this effect
1282 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1283 {
1284 if (ihit->effectMask & (1 << effIndex))
1285 {
1286 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1287 break;
1288 }
1289 }
1290 break;
1291 }
1292 default:
1293 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1294 return;
1295 }
1296 if (!referer)
1297 return;
1298
1299 Position const* center = nullptr;
1300 switch (targetType.GetReferenceType())
1301 {
1303 center = m_targets.GetSrcPos();
1304 break;
1306 center = m_targets.GetDstPos();
1307 break;
1311 center = referer;
1312 break;
1313 default:
1314 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1315 return;
1316 }
1317
1318 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1319 std::list<WorldObject*> targets;
1320 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1321 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1322
1323 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1324
1325 if (!targets.empty())
1326 {
1327 // Other special target selection goes here
1328 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1329 {
1331 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1332 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1333 maxTargets += (*j)->GetAmount();
1334
1335 Acore::Containers::RandomResize(targets, maxTargets);
1336 }
1337
1338 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1339 {
1340 if (Unit* unitTarget = (*itr)->ToUnit())
1341 AddUnitTarget(unitTarget, effMask, false);
1342 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1343 AddGOTarget(gObjTarget, effMask);
1344 }
1345 }
1346}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:91
Position const * GetSrcPos() const
Definition Spell.cpp:362
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8659
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:225
uint32 MaxAffectedTargets
Definition Spell.h:224

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1349{
1351
1352 switch (targetType.GetTarget())
1353 {
1354 case TARGET_DEST_CASTER:
1356 break;
1357 case TARGET_DEST_HOME:
1358 if (Player* playerCaster = m_caster->ToPlayer())
1359 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1360 break;
1361 case TARGET_DEST_DB:
1362 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1363 {
1366 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1367 else if (st->target_mapId == m_caster->GetMapId())
1368 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1369 }
1370 else
1371 {
1372 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1373 if (WorldObject* target = m_targets.GetObjectTarget())
1374 dest = SpellDestination(*target);
1375 }
1376 break;
1378 {
1379 float min_dis = m_spellInfo->GetMinRange(true);
1380 float max_dis = m_spellInfo->GetMaxRange(true);
1381 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1382 float x, y, z, angle;
1383 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1384 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1386
1387 float ground = m_caster->GetMapHeight(x, y, z, true);
1388 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1389 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1390 if (liquidData.Status)
1391 liquidLevel = liquidData.Level;
1392
1393 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1394 {
1397 finish(false);
1398 return;
1399 }
1400
1401 if (ground + 0.75 > liquidLevel)
1402 {
1405 finish(false);
1406 return;
1407 }
1408
1409 if (!m_caster->IsWithinLOS(x, y, z))
1410 {
1413 finish(false);
1414 return;
1415 }
1416
1417 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1418 break;
1419 }
1421 {
1422 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1423 Map* map = m_caster->GetMap();
1424 uint32 mapid = m_caster->GetMapId();
1425 uint32 phasemask = m_caster->GetPhaseMask();
1426 float collisionHeight = m_caster->GetCollisionHeight();
1427 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1428
1429 Position pos;
1430 Position lastpos;
1431 m_caster->GetPosition(startx, starty, startz, starto);
1432 pos.Relocate(startx, starty, startz, starto);
1433 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1434 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1435
1436 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1437 // the Z position may be slightly below the vmap ground level.
1438 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1439 // beneath the actual surface.
1440 //
1441 // Example:
1442 // actual vmap ground: -56.342392
1443 // Z position: -56.347195
1444 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1445 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1446
1447 bool isCasterInWater = m_caster->IsInWater();
1448 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1449 {
1450 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1451 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1452 float maxtravelDistZ = 2.65f;
1453 float overdistance = 0.0f;
1454 float totalpath = 0.0f;
1455 float beforewaterz = 0.0f;
1456 bool inwater = false;
1457 bool wcol = false;
1458 const float step = 2.0f;
1459 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1460 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1461 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1462 int j = 1;
1463 for (; j < (numChecks + 1); j++)
1464 {
1465 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1466 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1467 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1468 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1469
1470 if (j < 2)
1471 {
1472 prevZ = pos.GetPositionZ();
1473 }
1474 else
1475 {
1476 prevZ = tstZ;
1477 }
1478
1479 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1480 ground = tstZ;
1481
1482 if (!isCasterInWater)
1483 {
1484 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1485 {
1486 if (!(beforewaterz != 0.0f))
1487 {
1488 beforewaterz = prevZ;
1489 }
1490 tstZ = beforewaterz;
1491 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1492 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1493 }
1494 }
1495 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1496 {
1497 prevZ = pos.GetPositionZ();
1498 tstZ = pos.GetPositionZ();
1499 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1500
1501 inwater = true;
1502 if (inwater && (fabs(tstZ - ground) < 2.0f))
1503 {
1504 wcol = true;
1505 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1506 }
1507
1508 // if (j < 2)
1509 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1510 // else
1511 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1512 }
1513
1514 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1515 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1516 {
1517 if (inwater && !IsInWater)
1518 inwater = false;
1519
1520 // highest available point
1521 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1522 // upper or floor
1523 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1524 //lower than floor
1525 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1526
1527 //distance of rays, will select the shortest in 3D
1528 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1529 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1530 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1531 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1532 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1533 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1534
1535 if (srange1 < srange2)
1536 {
1537 tstZ = tstZ1;
1538 srange = srange1;
1539 }
1540 else if (srange3 < srange2)
1541 {
1542 tstZ = tstZ3;
1543 srange = srange3;
1544 }
1545 else
1546 {
1547 tstZ = tstZ2;
1548 srange = srange2;
1549 }
1550
1551 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1552 }
1553
1554 destx = tstX;
1555 desty = tstY;
1556 destz = tstZ;
1557
1558 totalpath += srange;
1559
1560 if (totalpath > distance)
1561 {
1562 overdistance = totalpath - distance;
1563 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1564 }
1565
1566 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1567 // check dynamic collision
1568 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1569
1570 // collision occured
1571 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1572 {
1573 if ((overdistance > 0.0f) && (overdistance < 1.f))
1574 {
1575 destx = prevX + overdistance * cos(pos.GetOrientation());
1576 desty = prevY + overdistance * sin(pos.GetOrientation());
1577 //LOG_ERROR("spells", "(collision) collision occured 1");
1578 }
1579 else
1580 {
1581 // move back a bit
1582 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1583 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1584 //LOG_ERROR("spells", "(collision) collision occured 2");
1585 }
1586
1587 // highest available point
1588 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1589 // upper or floor
1590 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1591 //lower than floor
1592 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1593
1594 //distance of rays, will select the shortest in 3D
1595 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1596 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1597 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1598
1599 if (srange1 < srange2)
1600 destz = destz1;
1601 else if (srange3 < srange2)
1602 destz = destz3;
1603 else
1604 destz = destz2;
1605
1606 if (inwater && destz < prevZ && !wcol)
1607 destz = prevZ;
1608 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1609
1610 // Don't make the player move backward from the xy adjustments by collisions.
1611 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1612 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1613 {
1614 destx = startx;
1615 desty = starty;
1616 destz = startz;
1617 }
1618
1619 break;
1620 }
1621 // we have correct destz now
1622 }
1623
1624 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1625 dest = SpellDestination(lastpos);
1626 }
1627 else
1628 {
1629 float z = pos.GetPositionZ();
1630 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1631 // check dynamic collision
1632 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1633
1634 // collision occured
1635 if (col || dcol)
1636 {
1637 // move back a bit
1638 destx = destx - (0.6 * cos(pos.GetOrientation()));
1639 desty = desty - (0.6 * sin(pos.GetOrientation()));
1640 }
1641
1642 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1643 dest = SpellDestination(lastpos);
1644 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1645 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1646 }
1647 break;
1648 }
1649 default:
1650 {
1651 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1652 float angle = targetType.CalcDirectionAngle();
1653 float objSize = m_caster->GetCombatReach();
1654
1655 switch (targetType.GetTarget())
1656 {
1658 dist = PET_FOLLOW_DIST;
1659 break;
1661 if (dist > objSize)
1662 dist = objSize + (dist - objSize) * float(rand_norm());
1663 break;
1668 {
1669 static float const DefaultTotemDistance = 3.0f;
1670 if (!m_spellInfo->Effects[effIndex].HasRadius())
1671 dist = DefaultTotemDistance;
1672 break;
1673 }
1674 default:
1675 break;
1676 }
1677
1678 if (dist < objSize)
1679 {
1680 dist = objSize;
1681 }
1682
1683 Position pos = dest._position;
1684 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1685
1686 dest.Relocate(pos);
1687 break;
1688 }
1689 }
1690
1691 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1692 m_targets.SetDst(dest);
1693}
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:800
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:794
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1487
@ TARGET_DEST_DB
Definition SharedDefines.h:1433
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1470
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1459
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1457
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1454
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1458
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1434
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1456
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1451
@ TARGET_DEST_HOME
Definition SharedDefines.h:1429
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1116
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:381
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional< uint8 > ReqLiquidType)
Definition Map.cpp:1297
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1145
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1594
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition Map.cpp:1572
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8687
float GetCollisionHeight() const override
Return collision height sent to client.
Definition Unit.cpp:20981
static VMapMgr2 * createOrGetVMapMgr()
Definition VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3037
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition Object.cpp:2644
Definition GridTerrainData.h:199
float Level
Definition GridTerrainData.h:204
LiquidStatus Status
Definition GridTerrainData.h:206
Definition SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), GROUND_HEIGHT_TOLERANCE, SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1769{
1770 WorldObject* target = nullptr;
1771 bool checkIfValid = true;
1772
1773 switch (targetType.GetTarget())
1774 {
1775 case TARGET_UNIT_CASTER:
1776 target = m_caster;
1777 checkIfValid = false;
1778 break;
1779 case TARGET_UNIT_MASTER:
1780 target = m_caster->GetCharmerOrOwner();
1781 break;
1782 case TARGET_UNIT_PET:
1783 target = m_caster->GetGuardianPet();
1784 if (!target)
1785 target = m_caster->GetCharm();
1786 break;
1788 if (m_caster->IsSummon())
1789 target = m_caster->ToTempSummon()->GetSummonerUnit();
1790 break;
1792 target = m_caster->GetVehicleBase();
1793 break;
1803 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1804 break;
1805 default:
1806 break;
1807 }
1808
1809 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1810
1811 if (target && target->ToUnit())
1812 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1813}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1512
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1517
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1513
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1515
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1518
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1442
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1516
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1514
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1507
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1511
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition Unit.cpp:18772
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:228

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1838{
1839 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1840 if (Player* modOwner = m_caster->GetSpellModOwner())
1841 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1842
1843 if (maxTargets > 1)
1844 {
1845 // mark damage multipliers as used
1846 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1847 if (effMask & (1 << k))
1848 m_damageMultipliers[k] = 1.0f;
1849 m_applyMultiplierMask |= effMask;
1850
1851 std::list<WorldObject*> targets;
1852 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1853 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1854
1855 // Chain primary target is added earlier
1856 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1857
1858 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1859 if (Unit* unitTarget = (*itr)->ToUnit())
1860 AddUnitTarget(unitTarget, effMask, false);
1861 }
1862}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1460
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition Spell.cpp:2111

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1047{
1048 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1049 {
1050 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1051 return;
1052 }
1053
1054 switch (targetType.GetTarget())
1055 {
1057 {
1058 // Xinef: All channel selectors have needed data passed in m_targets structure
1060 if (target)
1061 {
1062 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1063 // unit target may be no longer avalible - teleported out of map for example
1064 if (target && target->ToUnit())
1065 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1066 }
1067 else
1068 {
1069 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1070 }
1071 break;
1072 }
1077 {
1078 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1079 if (target)
1080 m_targets.SetDst(*target);
1081 }
1083 {
1084 if (channeledSpell->m_targets.GetUnitTarget())
1085 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1086 }
1087 else //if (!m_targets.HasDst())
1088 {
1089 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1090 }
1091 break;
1093 if (GetOriginalCaster())
1095 break;
1096 default:
1097 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1098 break;
1099 }
1100}
@ TARGET_DEST_CHANNEL_TARGET
Definition SharedDefines.h:1491
@ TARGET_UNIT_CHANNEL_TARGET
Definition SharedDefines.h:1492
@ TARGET_DEST_CHANNEL_CASTER
Definition SharedDefines.h:1521
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition Spell.cpp:474
bool HasDstChannel() const
Definition Spell.cpp:469

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1217{
1218 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1219 {
1220 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1221 return;
1222 }
1223 std::list<WorldObject*> targets;
1224 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1225 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1226 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1227 float coneAngle = M_PI / 2;
1228 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1229
1230 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1231 {
1232 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1233 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1234 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1235
1236 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1237
1238 if (!targets.empty())
1239 {
1240 // Other special target selection goes here
1241 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1242 {
1244 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1245 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1246 maxTargets += (*j)->GetAmount();
1247
1248 Acore::Containers::RandomResize(targets, maxTargets);
1249 }
1250
1251 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1252 {
1253 if (Unit* unit = (*itr)->ToUnit())
1254 {
1255 AddUnitTarget(unit, effMask, false);
1256 }
1257 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1258 {
1259 AddGOTarget(gObjTarget, effMask);
1260 }
1261 }
1262 }
1263 }
1264}
SpellTargetCheckTypes
Definition SpellInfo.h:113
SpellTargetObjectTypes
Definition SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1733{
1734 // set destination to caster if no dest provided
1735 // can only happen if previous destination target could not be set for some reason
1736 // (not found nearby target, or channel target for example
1737 // maybe we should abort the spell in such case?
1738 CheckDst();
1739
1741
1742 switch (targetType.GetTarget())
1743 {
1747 case TARGET_DEST_DEST:
1748 return;
1749 default:
1750 {
1751 float angle = targetType.CalcDirectionAngle();
1752 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1753 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1754 dist *= float(rand_norm());
1755
1756 Position pos = dest._position;
1757 m_caster->MovePosition(pos, dist, angle);
1758
1759 dest.Relocate(pos);
1760 break;
1761 }
1762 }
1763
1764 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1765 m_targets.ModDst(dest);
1766}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1443
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1501
@ TARGET_DEST_DEST
Definition SharedDefines.h:1502
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1503
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1444
void ModDst(Position const &pos)
Definition Spell.cpp:436
SpellDestination const * GetDst() const
Definition Spell.cpp:396
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2794

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, and TARGET_DEST_DYNOBJ_NONE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1103{
1104 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1105 {
1106 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1107 return;
1108 }
1109
1110 float range = 0.0f;
1111 switch (targetType.GetCheckType())
1112 {
1113 case TARGET_CHECK_ENEMY:
1114 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1115 break;
1116 case TARGET_CHECK_ALLY:
1117 case TARGET_CHECK_PARTY:
1118 case TARGET_CHECK_RAID:
1120 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1121 break;
1122 case TARGET_CHECK_ENTRY:
1125 break;
1126 default:
1127 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1128 break;
1129 }
1130
1131 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1132
1133 // handle emergency case - try to use other provided targets if no conditions provided
1134 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1135 {
1136 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1137 switch (targetType.GetObjectType())
1138 {
1141 {
1142 if (focusObject)
1143 AddGOTarget(focusObject, effMask);
1144 return;
1145 }
1146 break;
1149 {
1150 if (focusObject)
1152 return;
1153 }
1154 break;
1155 default:
1156 break;
1157 }
1158 }
1159
1160 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1161 if (!target)
1162 {
1163 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1164 return;
1165 }
1166
1167 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1168 if (!target)
1169 {
1170 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1171 return;
1172 }
1173
1174 switch (targetType.GetObjectType())
1175 {
1177 {
1178 if (Unit* unit = target->ToUnit())
1179 {
1180 AddUnitTarget(unit, effMask, true, false);
1181 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1182 // and if channeled spell has target 77, it requires unitTarget, set it here!
1183 // xinef: if we have NO unit target
1184 if (!m_targets.GetUnitTarget())
1185 {
1187 }
1188 }
1189 else
1190 {
1191 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1192 return;
1193 }
1194 break;
1195 }
1197 if (GameObject* gobjTarget = target->ToGameObject())
1198 AddGOTarget(gobjTarget, effMask);
1199 else
1200 {
1201 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1202 return;
1203 }
1204 break;
1206 m_targets.SetDst(*target);
1207 break;
1208 default:
1209 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1210 break;
1211 }
1212
1213 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1214}
@ TARGET_CHECK_PARTY
Definition SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition Spell.cpp:2089
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1837

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1696{
1698
1699 SpellDestination dest(*target);
1700
1701 switch (targetType.GetTarget())
1702 {
1705 break;
1706 default:
1707 {
1708 float angle = targetType.CalcDirectionAngle();
1709 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1710 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1711 {
1712 dist *= float(rand_norm());
1713 }
1714
1715 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1716 {
1718 }
1719
1720 Position pos = dest._position;
1721 target->MovePositionToFirstCollision(pos, dist, angle);
1722
1723 dest.Relocate(pos);
1724 break;
1725 }
1726 }
1727
1728 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1729 m_targets.SetDst(dest);
1730}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1478
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1480
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1489
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1468
@ UNIT_FIELD_BOUNDINGRADIUS
Definition UpdateFields.h:122

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1816{
1817 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1818
1820
1821 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1822
1823 if (target)
1824 {
1825 if (Unit* unit = target->ToUnit())
1826 AddUnitTarget(unit, 1 << effIndex, true, false);
1827 else if (GameObject* gobj = target->ToGameObject())
1828 AddGOTarget(gobj, 1 << effIndex);
1829
1830 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1831 }
1832 // Script hook can remove object target and we would wrongly land here
1833 else if (Item* item = m_targets.GetItemTarget())
1834 AddItemTarget(item, 1 << effIndex);
1835}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1879{
1880 if (!m_targets.HasTraj())
1881 return;
1882
1883 float dist2d = m_targets.GetDist2d();
1884 if (!dist2d)
1885 return;
1886
1887 Position srcPos = *m_targets.GetSrcPos();
1889 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1890
1891 std::list<WorldObject*> targets;
1892 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1894 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1895 if (targets.empty())
1896 return;
1897
1899
1900 float b = tangent(m_targets.GetElevation());
1901 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1902 if (a > -0.0001f)
1903 a = 0.f;
1904
1905 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1906 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1907 float bestDist = m_spellInfo->GetMaxRange(false);
1908 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
1909 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
1910
1911 // GameObjects don't cast traj
1912 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
1913 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
1914 {
1915 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
1916 continue;
1917
1918 if (Unit* unit = (*itr)->ToUnit())
1919 {
1920 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
1921 continue;
1922
1923 if (Creature* creatureTarget = unit->ToCreature())
1924 {
1925 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
1926 continue;
1927 }
1928 }
1929
1930 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
1931 float const objDist2d = srcPos.GetExactDist2d(*itr);
1932 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
1933
1934 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
1935 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
1936 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
1937 float const height = distToHitPoint * (a * distToHitPoint + b);
1938
1939 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
1940 continue;
1941
1942 if (distToHitPoint < bestDist)
1943 {
1944 bestDist = distToHitPoint;
1945 break;
1946 }
1947 }
1948
1949 if (dist2d > bestDist)
1950 {
1951 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
1952 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
1953 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1954
1955 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
1956 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1957 m_targets.ModDst(dest);
1958 }
1959}
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:85
@ CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES
Definition SharedDefines.h:2725
float tangent(float x)
Definition Spell.cpp:1864
#define TRAJECTORY_MISSILE_SIZE
Definition Spell.h:42
Definition Object.h:795
float GetElevation() const
Definition Spell.h:178
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1881
void SetOrientation(float orientation)
Definition Position.h:116

References ASSERT_NOTNULL, CallScriptDestinationTargetSelectHandlers(), SpellInfo::CheckTarget(), CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES, SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::SetOrientation(), SPELL_CAST_OK, sSpellMgr, tangent(), Object::ToCreature(), Object::ToUnit(), and TRAJECTORY_MISSILE_SIZE.

Referenced by SelectEffectImplicitTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
822{
823 // select targets for cast phase
825
826 uint32 processedAreaEffectsMask = 0;
827 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
828 {
829 // not call for empty effect.
830 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
831 if (!m_spellInfo->Effects[i].IsEffect())
832 continue;
833
834 // set expected type of implicit targets to be sent to client
835 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
836 if (implicitTargetMask & TARGET_FLAG_UNIT)
838 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
840
841 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
842 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
843
844 // Select targets of effect based on effect type
845 // those are used when no valid target could be added for spell effect based on spell target type
846 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
847 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
848 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
850
851 if (m_targets.HasDst())
853
855 {
856 // maybe do this for all spells?
857 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
858 {
860 finish(false);
861 return;
862 }
863
864 uint8 mask = (1 << i);
865 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
866 {
867 if (ihit->effectMask & mask)
868 {
870 break;
871 }
872 }
873 }
874 else if (m_auraScaleMask)
875 {
876 bool checkLvl = !m_UniqueTargetInfo.empty();
877 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
878 {
879 // remove targets which did not pass min level check
880 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
881 {
882 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
883 return true;
884 }
885
886 return false;
887 }), std::end(m_UniqueTargetInfo));
888
889 if (checkLvl && m_UniqueTargetInfo.empty())
890 {
892 finish(false);
893 }
894 }
895 }
896
897 if (uint64 dstDelay = CalculateDelayMomentForDst())
898 m_delayMoment = dstDelay;
899}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition SpellInfo.cpp:31
@ TARGET_FLAG_GAMEOBJECT
Definition SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition Spell.h:130
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition Spell.cpp:928
void SelectExplicitTargets()
Definition Spell.cpp:788
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2517
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:1961

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4629{
4630 if (result == SPELL_CAST_OK)
4631 return;
4632
4633 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4634 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4635
4636 caster->SendDirectMessage(&data);
4637}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4523
@ SMSG_CAST_FAILED
Definition Opcodes.h:334

References Player::SendDirectMessage(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4640{
4641 if (result == SPELL_CAST_OK)
4642 return;
4643
4644 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4645 return;
4646
4647 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4648 return;
4649
4650 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4652 result = SPELL_FAILED_DONT_REPORT;
4653
4655}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1119
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:149
bool IsCharmed() const
Definition Unit.h:1277

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5166{
5167 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5168 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5169 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5170 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5171
5172 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5173 data << m_caster->GetPackGUID();
5174 data << uint32(m_spellInfo->Id);
5175 data << uint32(duration);
5176
5177 m_caster->SendMessageToSet(&data, true);
5178
5181
5182 m_timer = duration;
5183 if (channelTarget)
5185
5187}
@ MSG_CHANNEL_START
Definition Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5134{
5135 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5136 data << m_caster->GetPackGUID();
5137 data << uint8(m_cast_count);
5138 data << uint32(m_spellInfo->Id);
5139 data << uint8(result);
5140 m_caster->SendMessageToSet(&data, true);
5141
5142 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5143 data << m_caster->GetPackGUID();
5144 data << uint8(m_cast_count);
5145 data << uint32(m_spellInfo->Id);
5146 data << uint8(result);
5147 m_caster->SendMessageToSet(&data, true);
5148}
@ SMSG_SPELL_FAILURE
Definition Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5033{
5034 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5035
5036 data << m_caster->GetPackGUID();
5037
5038 data << uint32(m_spellInfo->Id);
5039
5040 uint8 effCount = 0;
5041 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5042 {
5043 if (m_effectExecuteData[i])
5044 ++effCount;
5045 }
5046
5047 if (!effCount)
5048 return;
5049
5050 data << uint32(effCount);
5051 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5052 {
5053 if (!m_effectExecuteData[i])
5054 continue;
5055
5056 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5057
5058 data.append(*m_effectExecuteData[i]);
5059
5060 delete m_effectExecuteData[i];
5061 m_effectExecuteData[i] = nullptr;
5062 }
5063 m_caster->SendMessageToSet(&data, true);
5064}
@ SMSG_SPELLLOGEXECUTE
Definition Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2016{
2017 Player* player = m_caster->ToPlayer();
2018 if (!player)
2019 return;
2020
2021 if (gameObjTarget)
2022 {
2023 // Players shouldn't be able to loot gameobjects that are currently despawned
2024 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2025 {
2026 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2027 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2028 return;
2029 }
2030 // special case, already has GossipHello inside so return and avoid calling twice
2032 {
2034 return;
2035 }
2036
2037 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2038 return;
2039
2040 if (gameObjTarget->AI()->GossipHello(player, false))
2041 return;
2042
2043 switch (gameObjTarget->GetGoType())
2044 {
2046 gameObjTarget->UseDoorOrButton(0, false, player);
2047 return;
2049 gameObjTarget->UseDoorOrButton(0, false, player);
2050
2051 // Xinef: properly link possible traps
2052 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2053 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2054 return;
2058 return;
2059
2061 // triggering linked GO
2064 return;
2065
2067 // triggering linked GO
2068 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2070
2071 // Don't return, let loots been taken
2072 default:
2073 break;
2074 }
2075 }
2076
2077 // Send loot
2078 player->SendLoot(guid, loottype);
2079}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1579
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1573
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1366
void SendPreparedGossip(WorldObject *source)
Definition PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition PlayerGossip.cpp:32
struct GameObjectTemplate::@232::@236 questgiver
uint32 gossipID
Definition GameObjectData.h:72
uint32 linkedTrap
Definition GameObjectData.h:59
struct GameObjectTemplate::@232::@241 spellFocus
struct GameObjectTemplate::@232::@237 chest
uint32 linkedTrapId
Definition GameObjectData.h:90

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4658{
4659 if (result == SPELL_CAST_OK)
4660 return;
4661
4662 Unit* owner = m_caster->GetCharmerOrOwner();
4663 if (!owner)
4664 return;
4665
4666 Player* player = owner->ToPlayer();
4667 if (!player)
4668 return;
4669
4670 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4672
4673 player->SendDirectMessage(&data);
4674}
@ SMSG_PET_CAST_FAILED
Definition Opcodes.h:342

References Unit::GetCharmerOrOwner(), m_cast_count, m_caster, m_customError, m_spellInfo, Player::SendDirectMessage(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5190{
5191 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5192 // for player resurrections the name is looked up by guid
5193 std::string const sentName(m_caster->IsPlayer()
5194 ? ""
5195 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5196
5197 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5198 data << m_caster->GetGUID();
5199 data << uint32(sentName.size() + 1);
5200
5201 data << sentName;
5202 data << uint8(0); // null terminator
5203
5204 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5205 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5207 data << uint32(0);
5208 target->SendDirectMessage(&data);
5209}
@ SPELL_ATTR3_NO_RES_TIMER
Definition SharedDefines.h:508
@ SMSG_RESURRECT_REQUEST
Definition Opcodes.h:377

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, Player::SendDirectMessage(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4305{
4306 // xinef: properly add creature cooldowns
4307 if (!m_caster->IsPlayer())
4308 {
4310 {
4311 // xinef: this should be added here
4312 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4313
4314 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4317 {
4318 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4319 data << m_caster->GetGUID();
4321 data << uint32(m_spellInfo->Id);
4323 player->SendDirectMessage(&data);
4324 }
4325 }
4326 return;
4327 }
4328
4329 Player* _player = m_caster->ToPlayer();
4330
4331 // mana/health/etc potions, disabled by client (until combat out as declarate)
4333 {
4334 // need in some way provided data for Spell::finish SendCooldownEvent
4335 _player->SetLastPotionId(m_CastItem->GetEntry());
4336 return;
4337 }
4338
4339 // have infinity cooldown but set at aura apply
4340 // do not set cooldown for triggered spells (needed by reincarnation)
4345 return;
4346
4348}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:615
void SetLastPotionId(uint32 item_id)
Definition Player.h:1808
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:10891
uint32 RecoveryTime
Definition SpellInfo.h:348
bool RequireCooldownInfo() const
Definition SpellInfo.cpp:1182
@ SMSG_SPELL_COOLDOWN
Definition Opcodes.h:338

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4757{
4758 // not send invisible spell casting
4759 if (!IsNeedSendToClient(true))
4760 return;
4761
4762 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4763
4764 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4765
4766 // triggered spells with spell visual != 0
4768 castFlags |= CAST_FLAG_PENDING;
4769
4771 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4772
4773 // should only be sent to self, but the current messaging doesn't make that possible
4774 if (m_caster->IsPlayer() || m_caster->IsPet())
4775 {
4776 switch (m_spellInfo->PowerType)
4777 {
4778 case POWER_HEALTH:
4779 break;
4780 case POWER_RUNE:
4781 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4782 break;
4783 default:
4784 if (m_powerCost != 0)
4785 {
4786 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4787 }
4788 break;
4789 }
4790 }
4791
4792 if ((m_caster->IsPlayer())
4796 {
4797 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4798 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4799 }
4800
4802 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4803
4804 if (m_targets.HasTraj())
4805 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4806
4808 castFlags |= CAST_FLAG_NO_GCD;
4809
4810 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4811 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4812 {
4813 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4814 {
4815 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4816 {
4817 realCasterGUID = casterGameobject->GetPackGUID();
4818 }
4819 }
4820 }
4821
4822 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4823
4824 if (m_CastItem)
4825 data << m_CastItem->GetPackGUID();
4826 else
4827 data << realCasterGUID;
4828
4829 data << realCasterGUID;
4830 data << uint8(m_cast_count); // pending spell cast?
4831 data << uint32(m_spellInfo->Id); // spellId
4832 data << uint32(castFlags); // cast flags
4833 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4834
4835 WriteSpellGoTargets(&data);
4836
4837 m_targets.Write(data);
4838
4839 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4841
4842 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4843 {
4844 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4845 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4846 if (Player* player = m_caster->ToPlayer())
4847 {
4848 uint8 runeMaskInitial = m_runesState;
4849 uint8 runeMaskAfterCast = player->GetRunesState();
4850 data << uint8(runeMaskInitial); // runes state before
4851 data << uint8(runeMaskAfterCast); // runes state after
4852 for (uint8 i = 0; i < MAX_RUNES; ++i)
4853 {
4854 uint8 mask = (1 << i);
4855 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4856 {
4857 // float casts ensure the division is performed on floats as we need float result
4858 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4859 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4860 }
4861 }
4862 }
4863 }
4864 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4865 {
4866 data << m_targets.GetElevation();
4868 }
4869
4870 if (castFlags & CAST_FLAG_PROJECTILE)
4871 WriteAmmoToPacket(&data);
4872
4873 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4874 {
4875 data << uint32(0);
4876 data << uint32(0);
4877 }
4878
4880 {
4881 data << uint8(0);
4882 }
4883
4884 m_caster->SendMessageToSet(&data, true);
4885}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition SharedDefines.h:935
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition SharedDefines.h:394
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition Spell.h:66
@ CAST_FLAG_ADJUST_MISSILE
Definition Spell.h:64
@ CAST_FLAG_UNKNOWN_9
Definition Spell.h:55
@ CAST_FLAG_NO_GCD
Definition Spell.h:65
@ CAST_FLAG_PROJECTILE
Definition Spell.h:52
@ CAST_FLAG_POWER_LEFT_SELF
Definition Spell.h:58
@ CAST_FLAG_RUNE_LIST
Definition Spell.h:68
@ CAST_FLAG_PENDING
Definition Spell.h:47
Definition ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition Spell.cpp:179
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:347
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition Spell.cpp:4972
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4887
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8071
@ SMSG_SPELL_GO
Definition Opcodes.h:336
int32 CastTime
Definition DBCStructure.h:1761

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4677{
4678 if (!IsNeedSendToClient(false))
4679 return;
4680
4681 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4682
4683 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4684
4686 castFlags |= CAST_FLAG_PENDING;
4687
4689 castFlags |= CAST_FLAG_PROJECTILE;
4690
4691 if (m_caster->IsPlayer() || m_caster->IsPet())
4692 {
4693 switch (m_spellInfo->PowerType)
4694 {
4695 case POWER_HEALTH:
4696 break;
4697 case POWER_RUNE:
4698 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4699 break;
4700 default:
4701 if (m_powerCost != 0)
4702 {
4703 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4704 }
4705 break;
4706 }
4707 }
4708
4710 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4711
4712 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4713 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4714 {
4715 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4716 {
4717 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4718 {
4719 realCasterGUID = casterGameobject->GetPackGUID();
4720 }
4721 }
4722 }
4723
4724 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4725 if (m_CastItem)
4726 data << m_CastItem->GetPackGUID();
4727 else
4728 data << realCasterGUID;
4729
4730 data << realCasterGUID;
4731 data << uint8(m_cast_count); // pending spell cast?
4732 data << uint32(m_spellInfo->Id); // spellId
4733 data << uint32(castFlags); // cast flags
4734 data << int32(m_timer); // delay?
4735
4736 m_targets.Write(data);
4737
4738 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4740
4741 if (castFlags & CAST_FLAG_PROJECTILE)
4742 WriteAmmoToPacket(&data);
4743
4744 if (castFlags & CAST_FLAG_UNKNOWN_23)
4745 {
4746 data << uint32(0);
4747 data << uint32(0);
4748 }
4749
4750 m_caster->SendMessageToSet(&data, true);
4751
4754}
@ CAST_FLAG_UNKNOWN_23
Definition Spell.h:69
@ CAST_FLAG_HAS_TRAJECTORY
Definition Spell.h:48
@ SMSG_SPELL_START
Definition Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
560{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
575{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
573{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8414{
8415 switch (mod)
8416 {
8418 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8419 break;
8421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8422 break;
8424 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8425 break;
8427 m_spellValue->RadiusMod = (float)value / 10000;
8428 break;
8431 break;
8434 break;
8436 m_spellValue->AuraDuration = value;
8437 break;
8439 m_spellValue->ForcedCritResult = (bool)value;
8440 break;
8442 m_spellValue->MiscVal[0] = value;
8443 break;
8445 m_spellValue->MiscVal[1] = value;
8446 break;
8448 m_spellValue->MiscVal[2] = value;
8449 break;
8450 }
8451}
@ SPELLVALUE_AURA_STACK
Definition SpellDefines.h:118
@ SPELLVALUE_MISCVALUE1
Definition SpellDefines.h:122
@ SPELLVALUE_AURA_DURATION
Definition SpellDefines.h:119
@ SPELLVALUE_MISCVALUE2
Definition SpellDefines.h:123
@ SPELLVALUE_RADIUS_MOD
Definition SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition SpellDefines.h:120
@ SPELLVALUE_MISCVALUE0
Definition SpellDefines.h:121
bool ForcedCritResult
Definition Spell.h:228

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::MiscVal, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, SPELLVALUE_MISCVALUE0, SPELLVALUE_MISCVALUE1, SPELLVALUE_MISCVALUE2, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
494{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5974{
5975 Unit* caster = m_originalCaster;
5976 if (!caster)
5977 return;
5978
5979 if (caster->IsTotem())
5980 caster = caster->ToTotem()->GetOwner();
5981
5982 // in another case summon new
5983 uint8 summonLevel = caster->GetLevel();
5984
5985 // level of pet summoned using engineering item based at engineering skill level
5986 if (m_CastItem && caster->IsPlayer())
5987 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5988 {
5989 // xinef: few special cases
5990 if (proto->RequiredSkill == SKILL_ENGINEERING)
5991 {
5992 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5993 summonLevel = skill202 / 5;
5994 }
5995
5996 switch (m_spellInfo->Id)
5997 {
5998 // Dragon's Call
5999 case 13049:
6000 summonLevel = 55;
6001 break;
6002
6003 // Cleansed Timberling Heart: Summon Timberling
6004 case 5666:
6005 summonLevel = 7;
6006 break;
6007
6008 // Glowing Cat Figurine: Summon Ghost Saber
6009 case 6084:
6010 // minLevel 19, maxLevel 20
6011 summonLevel = 20;
6012 break;
6013
6014 // Spiked Collar: Summon Felhunter
6015 case 8176:
6016 summonLevel = 30;
6017 break;
6018
6019 // Dog Whistle: Summon Tracking Hound
6020 case 9515:
6021 summonLevel = 30;
6022 break;
6023
6024 // Barov Peasant Caller: Death by Peasant
6025 case 18307:
6026 case 18308:
6027 summonLevel = 60;
6028 break;
6029
6030 // Thornling Seed: Plant Thornling
6031 case 22792:
6032 summonLevel = 60;
6033 break;
6034
6035 // Cannonball Runner: Summon Crimson Cannon
6036 case 6251:
6037 summonLevel = 61;
6038 break;
6039 }
6040 }
6041
6042 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6043
6044 float radius = 5.0f;
6045 int32 duration = m_spellInfo->GetDuration();
6046
6047 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6048 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6049
6050 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6051 Map* map = caster->GetMap();
6052 TempSummon* summon = nullptr;
6053
6054 uint32 currMinionsCount = m_caster->m_Controlled.size();
6055 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6056
6057 for (uint32 count = 0; count < numGuardians; ++count)
6058 {
6059 Position pos;
6060
6061 // xinef: do not use precalculated position for effect summon pet in this function
6062 // it means it was cast by NPC and should have its position overridden unless the
6063 // target position is specified in the DB AND the effect has no or zero radius
6064 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6065 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6066 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6067 {
6068 pos = *destTarget;
6069 }
6070 else
6071 {
6072 // randomize position
6073 pos = m_caster->GetRandomPoint(*destTarget, radius);
6074 }
6075
6076 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6077 if (!summon)
6078 return;
6079
6080 // xinef: set calculated level
6081 summon->SetLevel(summonLevel);
6082
6083 // if summonLevel changed, set stats for calculated level
6084 if (summonLevel != caster->GetLevel())
6085 {
6086 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6087 }
6088
6089 // xinef: if we have more than one guardian, change follow angle
6090 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6091 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6092 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6093 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6094
6095 // xinef: move this here, some auras are added in initstatsforlevel!
6096 if (!summon->IsInCombat() && !summon->IsTrigger())
6097 {
6098 // summon->AI()->EnterEvadeMode();
6099 summon->GetMotionMaster()->Clear(false);
6101 }
6102
6103 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6104 summon->SetFaction(caster->GetFaction());
6105
6107 }
6108}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3173
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:189
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:238
bool IsTrigger() const
Definition Creature.h:80
Definition TemporarySummon.h:77
Unit * GetOwner() const
Definition TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition Unit.cpp:15490
virtual float GetFollowAngle() const
Definition Unit.h:1850

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5339{
5341 {
5343
5344 // wands don't have ammo
5345 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5346 return;
5347
5348 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5349 {
5350 if (pItem->GetMaxStackCount() == 1)
5351 {
5352 // decrease durability for non-stackable throw weapon
5354 }
5355 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5356 {
5357 // decrease items amount for stackable throw weapon
5358 uint32 count = 1;
5359 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5360 }
5361 }
5362 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5364 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5365 }
5366}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:687
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:620
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:145
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4814

References CONFIG_ENABLE_INFINITEAMMO, Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_spellInfo, PLAYER_AMMO_ID, RANGED_ATTACK, SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES, ItemTemplate::SubClass, sWorld, and Object::ToPlayer().

Referenced by handle_immediate(), spell_hun_explosive_shot::HandleFinish(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5212{
5213 if (!m_CastItem || !m_caster->IsPlayer())
5214 return;
5215
5216 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5218 return;
5219
5220 ItemTemplate const* proto = m_CastItem->GetTemplate();
5221
5222 if (!proto)
5223 {
5224 // This code is to avoid a crash
5225 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5226 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5227 return;
5228 }
5229
5230 bool expendable = false;
5231 bool withoutCharges = false;
5232
5233 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5234 {
5235 if (proto->Spells[i].SpellId)
5236 {
5237 // item has limited charges
5238 if (proto->Spells[i].SpellCharges)
5239 {
5240 if (proto->Spells[i].SpellCharges < 0)
5241 expendable = true;
5242
5243 int32 charges = m_CastItem->GetSpellCharges(i);
5244
5245 // item has charges left
5246 if (charges)
5247 {
5248 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5249 if (proto->Stackable == 1)
5250 m_CastItem->SetSpellCharges(i, charges);
5252 }
5253
5254 // all charges used
5255 withoutCharges = (charges == 0);
5256 }
5257 }
5258 }
5259
5260 if (expendable && withoutCharges)
5261 {
5262 uint32 count = 1;
5263 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5264
5265 // prevent crash at access to deleted m_targets.GetItemTarget
5267 m_targets.SetItemTarget(nullptr);
5268
5269 m_CastItem = nullptr;
5271 }
5272}
void SetSpellCharges(uint8 index, int32 value)
Definition Item.h:318
int32 Stackable
Definition ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5275{
5277 return;
5278
5279 //Don't take power if the spell is cast while .cheat power is enabled.
5280 if (m_caster->IsPlayer())
5282 return;
5283
5285 bool hit = true;
5286 if (m_caster->IsPlayer())
5287 {
5289 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5290 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5291 if (ihit->targetGUID == targetGUID)
5292 {
5293 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5294 {
5295 hit = false;
5296 //lower spell cost on fail (by talent aura)
5297 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5298 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5299 }
5300 break;
5301 }
5302 }
5303
5304 if (PowerType == POWER_RUNE)
5305 {
5306 TakeRunePower(hit);
5307 return;
5308 }
5309
5310 if (!m_powerCost)
5311 return;
5312
5313 // health as power used
5314 if (PowerType == POWER_HEALTH)
5315 {
5317 return;
5318 }
5319
5320 if (PowerType >= MAX_POWERS)
5321 {
5322 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5323 return;
5324 }
5325
5326 if (hit)
5328 else
5330
5331 // Set the five second timer
5332 if (PowerType == POWER_MANA && m_powerCost > 0)
5333 {
5335 }
5336}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1540
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5422
int32 ModifyHealth(int32 val)
Definition Unit.cpp:14180
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1114

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5492{
5493 if (!m_caster->IsPlayer())
5494 return;
5495
5496 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5497
5498 // do not take reagents for these item casts
5499 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5500 return;
5501
5502 Player* p_caster = m_caster->ToPlayer();
5503 if (p_caster->CanNoReagentCast(m_spellInfo))
5504 return;
5505
5506 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5507 {
5508 if (m_spellInfo->Reagent[x] <= 0)
5509 continue;
5510
5511 uint32 itemid = m_spellInfo->Reagent[x];
5512 uint32 itemcount = m_spellInfo->ReagentCount[x];
5513
5514 // if CastItem is also spell reagent
5515 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5516 {
5517 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5518 {
5519 // CastItem will be used up and does not count as reagent
5520 int32 charges = m_CastItem->GetSpellCharges(s);
5521 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5522 {
5523 ++itemcount;
5524 break;
5525 }
5526 }
5527
5528 m_CastItem = nullptr;
5530 }
5531
5532 // if GetItemTarget is also spell reagent
5533 if (m_targets.GetItemTargetEntry() == itemid)
5534 m_targets.SetItemTarget(nullptr);
5535
5536 p_caster->DestroyItemCount(itemid, itemcount, true);
5537 }
5538}
uint32 ItemId
Definition ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5423{
5425 return;
5426
5427 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5428 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5429 return;
5430
5431 Player* player = m_caster->ToPlayer();
5432 m_runesState = player->GetRunesState(); // store previous state
5433
5434 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5435
5436 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5437 {
5438 runeCost[i] = runeCostData->RuneCost[i];
5439 if (Player* modOwner = m_caster->GetSpellModOwner())
5440 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5441 }
5442
5443 runeCost[RUNE_DEATH] = 0; // calculated later
5444
5445 for (uint32 i = 0; i < MAX_RUNES; ++i)
5446 {
5447 RuneType rune = player->GetCurrentRune(i);
5448 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5449 {
5450 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5451 player->SetLastUsedRune(rune);
5452 runeCost[rune]--;
5453 }
5454 }
5455
5456 // Xinef: firstly consume death runes of base type
5457 // Xinef: in second loop consume all available
5458 for (uint8 loop = 0; loop < 2; ++loop)
5459 {
5460 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5461 if (runeCost[RUNE_DEATH] > 0)
5462 {
5463 for (uint8 i = 0; i < MAX_RUNES; ++i)
5464 {
5465 RuneType rune = player->GetCurrentRune(i);
5466 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5467 {
5468 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5469 player->SetLastUsedRune(rune);
5470 runeCost[rune]--;
5471 if (!loop)
5472 runeCost[player->GetBaseRune(i)]--;
5473
5474 // keep Death Rune type if missed
5475 if (didHit)
5476 player->RestoreBaseRune(i);
5477
5478 if (runeCost[RUNE_DEATH] == 0)
5479 break;
5480 }
5481 }
5482 }
5483 }
5484
5485 // you can gain some runic power when use runes
5486 if (didHit)
5487 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5488 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5489}
@ RUNE_UNHOLY
Definition Player.h:406
@ RUNE_BLOOD
Definition Player.h:405
@ RUNE_MISS_COOLDOWN
Definition Player.h:400
@ RATE_POWER_RUNICPOWER_INCOME
Definition WorldConfig.h:392
void SetLastUsedRune(RuneType type)
Definition Player.h:2515
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13366
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13395
bool NoRunicPowerGain() const
Definition DBCStructure.h:1812
uint32 runePowerGain
Definition DBCStructure.h:1809

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8831{
8833 if (!gcd)
8834 {
8835 // Xinef: fix for charmed pet spells with no cooldown info
8837 gcd = MIN_GCD;
8838 else
8839 return;
8840 }
8841
8842 if (m_caster->IsPlayer())
8844 return;
8845
8846 // Global cooldown can't leave range 1..1.5 secs
8847 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8848 // but as tests show are not affected by any spell mods.
8850 {
8851 // gcd modifier auras are applied only to own spells and only players have such mods
8852 if (m_caster->IsPlayer())
8854
8855 // Apply haste rating
8858 {
8859 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8860 }
8861
8862 if (gcd < MIN_GCD)
8863 gcd = MIN_GCD;
8864 else if (gcd > MAX_GCD)
8865 gcd = MAX_GCD;
8866 }
8867
8868 // Only players or controlled units have global cooldown
8869 if (m_caster->GetCharmInfo())
8871 else if (m_caster->IsPlayer())
8873}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8815
@ MAX_GCD
Definition Spell.cpp:8816
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition CharmInfo.cpp:419

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4351{
4352 // update pointers based at it's GUIDs
4353 if (!UpdatePointers())
4354 {
4355 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4356 cancel();
4357 return;
4358 }
4359
4361 {
4362 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4363 cancel();
4364 return;
4365 }
4366
4367 // check if the player caster has moved before the spell finished
4368 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4369 if ((m_caster->IsPlayer() && m_timer != 0) &&
4372 {
4373 // don't cancel for melee, autorepeat, triggered and instant spells
4375 cancel(true);
4376 }
4377
4378 switch (m_spellState)
4379 {
4381 {
4382 if (m_timer > 0)
4383 {
4384 if (difftime >= (uint32)m_timer)
4385 m_timer = 0;
4386 else
4387 m_timer -= difftime;
4388 }
4389
4390 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4391 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4392 cast(!m_casttime);
4393 break;
4394 }
4396 {
4397 if (m_timer)
4398 {
4399 if (m_timer > 0)
4400 {
4401 if (difftime >= (uint32)m_timer)
4402 m_timer = 0;
4403 else
4404 m_timer -= difftime;
4405 }
4406 }
4407
4408 if (m_timer == 0)
4409 {
4411
4412 finish();
4413
4414 // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts
4415 if (Creature* creatureCaster = m_caster->ToCreature())
4416 if (creatureCaster->IsAIEnabled)
4417 creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE);
4418 }
4419 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4420 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4421 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4422 // Xinef: so the aura can be removed in different updates for all units
4423 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4424 {
4425 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4427 finish();
4428 }
4429 break;
4430 }
4431 default:
4432 break;
4433 }
4434}
@ SPELL_FINISHED_CHANNELING_COMPLETE
Definition Spell.h:100
bool UpdateChanneledTargetList()
Definition Spell.cpp:3324

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_FINISHED_CHANNELING_COMPLETE, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, Object::ToCreature(), UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3325{
3326 // Not need check return true
3328 return true;
3329
3330 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3331 uint8 channelAuraMask = 0;
3332 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3334 channelAuraMask |= 1 << i;
3335
3336 channelAuraMask &= channelTargetEffectMask;
3337
3338 float range = 0;
3339 if (channelAuraMask)
3340 {
3342 if (range == 0)
3343 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3344 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3345 {
3346 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3347 break;
3348 }
3349
3350 if (Player* modOwner = m_caster->GetSpellModOwner())
3351 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3352
3353 // xinef: add little tolerance level
3354 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3355 }
3356
3357 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3358 {
3359 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3360 {
3361 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3362
3363 if (!unit)
3364 continue;
3365
3366 if (IsValidDeadOrAliveTarget(unit))
3367 {
3368 if (channelAuraMask & ihit->effectMask)
3369 {
3371 {
3372 if (m_caster != unit)
3373 {
3374 if (!m_caster->IsWithinDistInMap(unit, range))
3375 {
3376 ihit->effectMask &= ~aurApp->GetEffectMask();
3377 unit->RemoveAura(aurApp);
3378 continue;
3379 }
3380 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3383 }
3384 }
3385 else // aura is dispelled
3386 continue;
3387 }
3388
3389 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3390 }
3391 }
3392 }
3393
3394 // Xinef: not all effects are covered, remove applications from all targets
3395 if (channelTargetEffectMask != 0)
3396 {
3397 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3398 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3399 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3400 if (IsValidDeadOrAliveTarget(unit))
3402 {
3403 ihit->effectMask &= ~aurApp->GetEffectMask();
3404 unit->RemoveAura(aurApp);
3405 }
3406 }
3407
3408 // is all effects from m_needAliveTargetMask have alive targets
3409 return channelTargetEffectMask == 0;
3410}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:444
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8203
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5631
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:19821
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1354

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7842{
7845 else
7846 {
7849 m_originalCaster = nullptr;
7850 }
7851
7853 {
7855 // cast item not found, somehow the item is no longer where we expected
7856 if (!m_CastItem)
7857 return false;
7858 }
7859 else
7860 m_CastItem = nullptr;
7861
7863
7864 // further actions done only for dest targets
7865 if (!m_targets.HasDst())
7866 return true;
7867
7868 // cache last transport
7869 WorldObject* transport = nullptr;
7870
7871 // update effect destinations (in case of moved transport dest target)
7872 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7873 {
7874 SpellDestination& dest = m_destTargets[effIndex];
7875 if (!dest._transportGUID)
7876 continue;
7877
7878 if (!transport || transport->GetGUID() != dest._transportGUID)
7880
7881 if (transport)
7882 {
7883 dest._position.Relocate(transport);
7885 }
7886 }
7887
7888 return true;
7889}
void Update(Unit *caster)
Definition Spell.cpp:479
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition Position.cpp:66
Position _transportOffset
Definition Spell.h:115
ObjectGuid _transportGUID
Definition Spell.h:114

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4888{
4889 uint32 ammoInventoryType = 0;
4890 uint32 ammoDisplayID = 0;
4891
4892 if (m_caster->IsPlayer())
4893 {
4895 if (pItem)
4896 {
4897 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4898 if (ammoInventoryType == INVTYPE_THROWN)
4899 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4900 else
4901 {
4903 if (ammoID)
4904 {
4905 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4906 if (pProto)
4907 {
4908 ammoDisplayID = pProto->DisplayInfoID;
4909 ammoInventoryType = pProto->InventoryType;
4910 }
4911 }
4912 else if (m_caster->HasAura(46699)) // Requires No Ammo
4913 {
4914 ammoDisplayID = 5996; // normal arrow
4915 ammoInventoryType = INVTYPE_AMMO;
4916 }
4917 }
4918 }
4919 }
4920 else
4921 {
4922 uint32 nonRangedAmmoDisplayID = 0;
4923 uint32 nonRangedAmmoInventoryType = 0;
4924 for (uint8 i = 0; i < 3; ++i)
4925 {
4927 {
4928 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4929 {
4930 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4931 {
4932 switch (itemEntry->SubclassID)
4933 {
4935 ammoDisplayID = itemEntry->DisplayInfoID;
4936 ammoInventoryType = itemEntry->InventoryType;
4937 break;
4940 ammoDisplayID = 5996; // is this need fixing?
4941 ammoInventoryType = INVTYPE_AMMO;
4942 break;
4944 ammoDisplayID = 5998; // is this need fixing?
4945 ammoInventoryType = INVTYPE_AMMO;
4946 break;
4947 default:
4948 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4949 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4950 break;
4951 }
4952
4953 if (ammoDisplayID)
4954 break;
4955 }
4956 }
4957 }
4958 }
4959
4960 if (!ammoDisplayID && !ammoInventoryType)
4961 {
4962 ammoDisplayID = nonRangedAmmoDisplayID;
4963 ammoInventoryType = nonRangedAmmoInventoryType;
4964 }
4965 }
4966
4967 *data << uint32(ammoDisplayID);
4968 *data << uint32(ammoInventoryType);
4969}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition UpdateFields.h:116
Definition DBCStructure.h:1141
uint32 DisplayInfoID
Definition ItemTemplate.h:625

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4524{
4525 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4526 data << uint32(spellInfo->Id);
4527 data << uint8(result); // problem
4528 switch (result)
4529 {
4531 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4532 break;
4533 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4534 // hardcode areas limitation case
4535 switch (spellInfo->Id)
4536 {
4537 case 41617: // Cenarion Mana Salve
4538 case 41619: // Cenarion Healing Salve
4539 data << uint32(3905);
4540 break;
4541 case 41618: // Bottled Nethergon Energy
4542 case 41620: // Bottled Nethergon Vapor
4543 data << uint32(3842);
4544 break;
4545 case 45373: // Bloodberry Elixir
4546 data << uint32(4075);
4547 break;
4548 default: // default case (don't must be)
4549 data << uint32(0);
4550 break;
4551 }
4552 break;
4554 if (spellInfo->Totem[0])
4555 data << uint32(spellInfo->Totem[0]);
4556 if (spellInfo->Totem[1])
4557 data << uint32(spellInfo->Totem[1]);
4558 break;
4560 if (spellInfo->TotemCategory[0])
4561 data << uint32(spellInfo->TotemCategory[0]);
4562 if (spellInfo->TotemCategory[1])
4563 data << uint32(spellInfo->TotemCategory[1]);
4564 break;
4568 data << uint32(spellInfo->EquippedItemClass);
4569 data << uint32(spellInfo->EquippedItemSubClassMask);
4570 break;
4572 {
4573 uint32 item = 0;
4574 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4575 if (spellInfo->Effects[eff].ItemType)
4576 item = spellInfo->Effects[eff].ItemType;
4577 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4578 if (proto && proto->ItemLimitCategory)
4579 data << uint32(proto->ItemLimitCategory);
4580 break;
4581 }
4583 data << uint32(customError);
4584 break;
4586 {
4587 uint32 missingItem = 0;
4588 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4589 {
4590 if (spellInfo->Reagent[i] <= 0)
4591 continue;
4592
4593 uint32 itemid = spellInfo->Reagent[i];
4594 uint32 itemcount = spellInfo->ReagentCount[i];
4595
4596 if (!caster->HasItemCount(itemid, itemcount))
4597 {
4598 missingItem = itemid;
4599 break;
4600 }
4601 }
4602
4603 data << uint32(missingItem); // first missing item
4604 break;
4605 }
4607 data << uint32(spellInfo->Mechanic);
4608 break;
4610 data << uint32(spellInfo->EquippedItemSubClassMask);
4611 break;
4613 data << uint32(0); // Item entry
4614 data << uint32(0); // Count
4615 break;
4617 data << uint32(0); // SkillLine.dbc Id
4618 data << uint32(0); // Amount
4619 break;
4621 data << uint32(0); // Skill level
4622 break;
4623 default:
4624 break;
4625 }
4626}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition SharedDefines.h:1014
@ SPELL_FAILED_FISHING_TOO_LOW
Definition SharedDefines.h:1141
@ SPELL_FAILED_MIN_SKILL
Definition SharedDefines.h:1110
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition SharedDefines.h:1107
@ SPELL_FAILED_REQUIRES_AREA
Definition SharedDefines.h:1061

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

4973{
4974 // This function also fill data for channeled spells:
4975 // m_needAliveTargetMask req for stop channelig if one target die
4976 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4977 {
4978 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
4979 // possibly SPELL_MISS_IMMUNE2 for this??
4980 ihit->missCondition = SPELL_MISS_IMMUNE2;
4981 }
4982
4983 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
4984 // sending more than 255 targets crashes the client (since count sent would be wrong)
4985 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
4986 // target conditions but we still need to limit the number of targets sent and keeping
4987 // correct count for both hit and miss).
4988
4989 uint32 hit = 0;
4990 std::size_t hitPos = data->wpos();
4991 *data << (uint8)0; // placeholder
4992 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
4993 {
4994 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
4995 {
4996 *data << ihit->targetGUID;
4997 // Xinef: No channeled spell checked, no anything
4998 //m_channelTargetEffectMask |=ihit->effectMask;
4999 ++hit;
5000 }
5001 }
5002
5003 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5004 {
5005 *data << ighit->targetGUID; // Always hits
5006 ++hit;
5007 }
5008
5009 uint32 miss = 0;
5010 std::size_t missPos = data->wpos();
5011 *data << (uint8)0; // placeholder
5012 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5013 {
5014 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5015 {
5016 *data << ihit->targetGUID;
5017 *data << uint8(ihit->missCondition);
5018 if (ihit->missCondition == SPELL_MISS_REFLECT)
5019 *data << uint8(ihit->reflectResult);
5020 ++miss;
5021 }
5022 }
5023 // Reset m_needAliveTargetMask for non channeled spell
5024 // Xinef: Why do we reset something that is not set??????
5025 //if (!m_spellInfo->IsChanneled())
5026 // m_channelTargetEffectMask = 0;
5027
5028 data->put<uint8>(hitPos, (uint8)hit);
5029 data->put<uint8>(missPos, (uint8)miss);
5030}
std::size_t wpos() const
Definition ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Symbol Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_reflectionTarget

Unit* Spell::m_reflectionTarget
protected

◆ m_reflectionTargetGuid

ObjectGuid Spell::m_reflectionTargetGuid
protected

◆ m_reflectionTargetPosition

Position Spell::m_reflectionTargetPosition
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakeAmmo(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSkinPlayerCorpse(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and Spell().


The documentation for this class was generated from the following files: